2016-03-11 5 views
0

Я пытаюсь изучить классы типов в haskell. Я пишу следующий скрипт и поднял ошибку. Я не могу понять, почему компилятор думает о v как конкретный тип, в то время как это просто параметр для класса Boxer.Почему компилятор дает ошибку на следующий код haskell?

data Box1 a b = Box1 Double a [b] 

class Boxer v where 
    foo :: (v a b) -> Double 

instance Boxer (Box1 a b) where 
    foo (Box1 r s t) = r 

он выдает ошибку в строке 7: 8:

Couldn't match type `v' with `Box1' 
    `v' is a rigid type variable bound by 
     the type signature for foo :: v a b -> Double at file1.hs:4:10 
Expected type: v a b 
    Actual type: Box1 a b 
Relevant bindings include 
    foo :: v a b -> Double (bound at file1.hs:7:3) 
In the pattern: Box1 r s t 
In an equation for `foo': foo (Box1 r s t) = r 
Failed, modules loaded: none. 
+0

В этом случае ошибка, вероятно, связано с углублением - 'декларация Foo' не связана с класса' Boxer', поэтому он ожидает функцию типа 'ForAll против A B. v a b -> Double'. Кроме того, 'instance Boxer (Box1 a b)' неверен - это должен быть «экземпляр Boxer Box1». Первая будет ошибкой типа, если функция 'foo' была правильно связана с классом« Боксер ». – user2407038

+0

@ пользователь2407038 большое спасибо. Это была действительно ошибка из-за отступов. Но не могли бы вы объяснить, когда я создаю экземпляр Foldable, там компилятор не позволяет мне делать экземпляр Foldable Box1. Он просит добавить больше параметров в Box1. –

+0

Вам нужно будет написать 'instance Foldable (Box1 a)' - класс 'Foldable' принимает параметр вида' * -> * ', тогда как тип' Box1' - '* -> * -> *'. – user2407038

ответ

1

Особая проблема была вызвана неправильным отступом. Хотя было другое, что я делал неправильно. Таким образом, следующая версия компилируется:

data Box1 a b = Box1 Double a [b] 

class Boxer v where 
    foo :: (v a b) -> Double 

instance Boxer Box1 where 
    foo (Box1 r s t) = r 
2

В вашем случае, компилятор должен создать экземпляр v с Box1 a b. В частности, он должен создать экземпляр v a b с чем-то вроде (Box1 a b) a b –, за исключением как a переменные исходят из другого места; они фактически устраняются до (Box1 a b) a1 b1. Это то же самое, что и Box1 a b a1 b1.

foo :: Box1 a b a1 b1 -> Double 

В этом смысл?

Проблема заключается в том, что вы путаете функцию в (типа), а именноBox1 с результате применения указанной функции для некоторых аргументов типа. В виды не совпадают:

GHCi> :k Boxer 
Boxer :: (* -> * -> *) -> Constraint 
GHCi> :k (Box1 Int String) 
Box1 Int String :: * 

* -> * -> * является своего рода функция типа/типа конструктора с двумя аргументами, так это то, что Boxer потребности. В то время как Box1 a b - это просто тип, без аргументов. Не соответствует! OTOH,

GHCi> :k Box1 
Box1 :: * -> * -> * 
+0

Это относится к семантической ошибке в коде, но ошибка типа в OP связана с неправильным отступом в исходном коде. – user2407038

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