2015-11-27 2 views
4

Я еще новичок в Haskell и Я этот кусок кода, но GHC не компилирует и дает мне ошибкуHaskell не может соответствовать типу

Это код:

data QT a = C a | Q (QT a) (QT a) (QT a) (QT a) deriving (Show) 

moltiply :: QT a -> Int -> QT a 
moltiply (C a) x = (C (a * x)) 
moltiply (Q a b c d) x = Q (moltiply a x) (moltiply b x) (moltiply c x) (moltiply d x) 

И это ошибка я получаю:

Couldn't match expected type ‘a’ with actual type ‘Int’ 
     ‘a’ is a rigid type variable bound by 
      the type signature for multiply :: QT a -> Int -> QT a 
      at file.hs:12:15 
    Relevant bindings include 
     a :: a (bound at file.hs:13:15) 
     multiply :: QT a -> Int -> QT a 
     (bound at file.hs:13:1) 
    In the second argument of ‘(*)’, namely ‘x’ 
    In the first argument of ‘C’, namely ‘(a * x)’ 

ответ

8

Когда вы пишете

moltiply :: QT a -> Int -> QT a 

вы говорите г GHC, что эта функция будет работать с любым типом a внутри вашего QT типа, но тогда вы пишете

moltiply (C a) x = (C (a * x)) 

и попытаться умножить значение a, которое может быть любого типа с Int. Кажется, это не так?

Вы можете исправить это двумя способами:

  1. Спросите GHCI, что самый общий тип moltiply является удаление сигнатуру типа и загрузки файла в GHCi:

    λ> :t moltiply 
    moltiply :: Num a => QT a -> a -> QT a 
    

    Тогда вам можете добавить подпись этого типа в исходный файл (хорошо для документации) или оставить функцию без подписи типа.

  2. Придерживайтесь Int, говоря, что moltiply требует QT чтобы содержать Int:

    moltiply :: QT Int -> Int -> QT Int 
    
2

Единственное, что вы можете умножить на Int используя * еще один Int. Вам нужно либо ограничить тип подписи

moltiply :: QT Int -> Int -> QT Int 

или обобщать его

moltiply :: Num a => QT a -> a -> QT a 

или изменить реализацию на что-то вроде

moltiply :: (Num a, Integral b) => QT a -> b -> QT a 
moltiply (C a) x = (C (a * fromIntegral x)) 
moltiply (Q a b c d) x = Q (moltiply a x) (moltiply b x) (moltiply c x) (moltiply d x) 
Смежные вопросы