2009-12-01 31 views
8

我有一個Haskell typeclass問題。我無法理解這個(看似合理的)程序在GHC下編譯的語法。Haskell typeclass

import Control.Concurrent.MVar 

blah1 :: [a] -> IO ([a]) 
blah1 = return 

blah2 :: [a] -> IO (MVar [a]) 
blah2 = newMVar 

class Blah b where 
    blah :: [a] -> IO (b a) 

instance Blah [] where 
    blah = blah1 

-- BOOM 
instance Blah (MVar []) where 
    blah = blah2 

main :: IO() 
main = do 
    putStrLn "Ok" 

我收到以下錯誤消息,哪一種是有道理的,但我不知道如何解決它:

`[]' is not applied to enough type arguments 
Expected kind `*', but `[]' has kind `* -> *' 
In the type `MVar []' 
In the instance declaration for `Blah (MVar [])' 

回答

12

你想要的是不直接表達。這可能是接近你會得到:

newtype MVarList a = MVarList (MVar [a]) 
instance Blah MVarList where 
    blah = fmap MVarList . newMVar 
+0

我試着玩弄這個來了解爲什麼'blah'返回IO(MVar [a])''是不可能的。是否因爲'Blah'的類定義中的「b」類型變量必須引用單個類型? – 2009-12-01 18:42:59

+0

它看起來像「b」型變量必須是* - > *類型,並且沒有辦法從'MyType - > MVar [MyType]'寫出一個類型表達式。 – 2009-12-01 18:46:23

+1

正確。對於函數,存在'(。)::(b - > c) - >(a - > b) - > a - > c',但是rank-1(或rank-n)類型沒有這種組合。 – ephemient 2009-12-01 19:11:34

2

我念叨Conal Elliott的TypeCompose庫,並提醒這個問題。這裏有一個如何做類型層次組合的例子。

{-# LANGUAGE TypeOperators #-} 
{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE TypeSynonymInstances #-} 
module Main where 

... 

import Control.Compose 

... 

instance Blah (MVar `O` []) where 
    blah = liftM O . blah2 

...