Проблемы с пониманием системы типов Haskell

Сейчас я пытаюсь выполнить 20 промежуточных упражнений на Haskell. Мне удалось выполнить первые три упражнения (но это потому, что furry == fmap и Learn You a Haskell уже имеют эти реализации) . В настоящее время я застрял на экземпляре, который говорит:

instance Fluffy (EitherLeft t) where                                        
  furry = error "todo"

Я не очень понимаю, что делать. В Learn You Haskell есть переменная newtype с именем Pair, которая принимает кортеж. Затем они могут выполнять сопоставление с образцом как таковое:

  fmap f (Pair (x,y)) = Pair (f x, y)

Я подумал, может быть, вы могли бы сделать что-то подобное в моей ситуации:

  furry f (EitherLeft (Either a b)) = EitherLeft (Either (f a) b)

Но это не работает:

Not in scope: data constructor `Either'

Я подумал, может быть, я бы import Data.Either потому что у него могут быть какие-то важные вещи, которых нет у меня. Но это не имело значения.

Я также пытался заставить работать только это:

  furry f (EitherLeft a b) = error "todo"

Но и это не работает:

Constructor `EitherLeft' should have 1 argument, but has been given 2

Я тоже не мог заставить это работать:

  furry f (Right x) = (Right f x)
  furry f (Left x) = Left x

Что дало ошибку:

Couldn't match expected type `EitherLeft t a'
            with actual type `Either t0 t1'

Мне удалось получить только:

  furry f (EitherLeft t) = error "todo"

работать. Но я понятия не имею, что делать с t.

Мне не обязательно нужен ответ. Мне просто нужна подсказка, что делать, потому что я читаю, и я вроде как понимаю примеры, но я действительно не могу понять, как кодировать этот материал самостоятельно.

Спасибо, Дэн, вот что я придумал для своего решения:

instance Fluffy (EitherLeft t) where                     
  furry f (EitherLeft (Left x)) = EitherLeft $ Left  (f x)                   
  furry f (EitherLeft (Right x)) = EitherLeft $ Right x

person Dair    schedule 21.08.2012    source источник
comment
это может сбивать с толку, если поначалу сохранять прямую разницу между именами типов и именами конструкторов, поэтому вот правило: в определении типа data Foo = Foo имя с заглавной буквы должно стоять слева от = только когда-либо появляется в сигнатурах типов и объявлениях экземпляров классов. Имя, написанное с заглавной буквы справа от =, появляется только в коде.   -  person jberryman    schedule 21.08.2012
comment
Я не думаю, что это хорошая практика - указывать ваше решение в вопросе. Из-за этого будущие читатели не поймут, с чем вы застряли и что вы уже проработали.   -  person Ben Millwood    schedule 30.08.2012


Ответы (1)


Проблема, с которой вы столкнулись, заключается в том, что тип данных Someone не имеет конструктора данных с именем Doesn, в основном тип Both выглядит так:

data Either a b = Left a
                | Right b

Таким образом, значение может иметь тип Either a b , но нет значения типа Either "one" 1 или чего-то подобного, а вместо него Left "one" или Right 1.

Таким образом, в случае EitherLeft его значения будут выглядеть как EitherLeft (Left a) или EitherLeft (Right b), и их необходимо сопоставлять с образцом как таковым.

person Dan Feltey    schedule 21.08.2012