2013-05-15 2 views
1

В следующем коде Haskell функция typeError не проверяется typecheck.Состав функции Haskell - ошибочно выведенный тип

wrap x = [x] 

listf :: [[a]] -> [[a]] 
listf = id 

typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

typeError :: [a] -> [[a]] 
typeError = wrap . listf 

GHC производит эту ошибку, если это раскомментирована:

Couldn't match type `a' with `[a0]' 
    `a' is a rigid type variable bound by 
     the type signature for typeError :: [a] -> [[a]] at tim.hs:10:1 
Expected type: [a] -> [a] 
    Actual type: [[a0]] -> [[a0]] 
In the second argument of `(.)', namely `listf' 
In the expression: wrap . listf 

Я не понимаю, почему. a должны быть в состоянии объединиться с [a0] - они являются независимыми переменными типа. Это именно тот тип, который он запрашивает для typeCheck - но не тогда, когда используется оператор ..

Объятия производит очень похожий, а так же паразитный, сообщение об ошибке:

ERROR "repro.hs":10 - Inferred type is not general enough 
*** Expression : typeError 
*** Expected type : [a] -> [[a]] 
*** Inferred type : [[a]] -> [[[a]]] 

Кроме того, это работает отлично:

listf' :: [a] -> [a] 
listf' = id 

typeCheck' :: [a] -> [[a]] 
typeCheck' = wrap . listf' 

Проблема возникает только с [[а]] или [ [[a]]] или больше. Какая сделка здесь?

ответ

5

Вы, похоже, изменили состав функции здесь.

-- This 
typeCheck :: [a] -> [[a]] 
typeCheck x = listf (wrap x) 

-- is the same as 
typeCheck' :: [a] -> [[a]] 
typeCheck' = listf . wrap 

-- while this 
typeError :: [a] -> [[a]] 
typeError = wrap . listf 

-- is the same as 
typeError' :: [a] -> [[a]] 
typeError' x = wrap (listf x) 

Теперь, надеюсь, будет очевидно, почему это не работает. listf требует, чтобы его аргумент был [[a]], но подпись typeError утверждает, что она работает для любого [a].

+0

Черт, вот что я получаю за попытку исправить ошибку в этом коде после многих лет не делая Haskell .. спасибо. – banana

Смежные вопросы