Функтор и складываемые экземпляры для типа данных Stream - PullRequest
1 голос
/ 20 июня 2020

У меня возникли проблемы при попытке реализовать здесь код Криса Пеннера https://github.com/ChrisPenner/comonads-by-example/blob/master/docs/rendered/01-streams.pdf.

В частности, в следующем фрагменте кода:

data Stream a = a :> Stream a
     deriving (Functor, Foldable)

{-instance Functor Stream where                                          
     f(x:>xs) = (f x):>(fmap f xs) -}

fromlist :: [a] -> Stream a
fromlist xs = go (cycle xs)
   where
     go (a: rest)= a :> go rest

countStream :: Stream Int
countStream = fromlist [0..]

это дает следующие ошибки:

comonads.hs:17:16: error:
   • Can't make a derived instance of ‘Functor Stream’:
       You need DeriveFunctor to derive an instance for this class
   • In the data declaration for ‘Stream’
  |
17 |      deriving (Functor, Foldable)
  |                ^^^^^^^

comonads.hs:17:25: error:
   • Can't make a derived instance of ‘Foldable Stream’:
       You need DeriveFoldable to derive an instance for this class
   • In the data declaration for ‘Stream’
  |
17 |      deriving (Functor, Foldable) 

Я попытался написать объявление экземпляра для типа данных Stream (полагая, что это позволит избежать проблемы), но это тоже не работает. Как я могу решить свою проблему?

1 Ответ

5 голосов
/ 20 июня 2020

По умолчанию Haskell не может генерировать экземпляры Foldable и Functor. В Глава 11. Спецификация производных экземпляров отчета Haskell 2010 указывается, что он может автоматически получить экземпляр класса типов C заданный :

  1. C является одним из Eq, Ord, Enum, Bounded, Show или Read.

(…)

Вы можете использовать DeriveFoldable и DeriveFunctor языковые расширения Glasgow Haskell Compiler (GH C) , чтобы включить это:

{-# LANGUAGE <b>DeriveFoldable, DeriveFunctor</b> #-}

data Stream a = a :> Stream a
     deriving (Functor, Foldable)

fromlist :: [a] -> Stream a
fromlist xs = go (cycle xs)
   where go (a: rest) = a :> go rest

countStream :: Stream Int
countStream = fromList [0..]

или вы можете указать экземпляр самостоятельно, например:

{-# LANGUAGE DeriveFoldable #-}

data Stream a = a :> Stream a
     deriving (Foldable)

instance Functor Stream where
    <b>fmap</b> f (x:>xs) = f x :> fmap f xs

Существуют и другие расширения, например, чтобы сделать его экземпляром Traversable, Generic, Lift, et c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...