Haskell 流数据类型的函子和可折叠实例

Haskell 流数据类型的函子和可折叠实例,haskell,Haskell,我在这里尝试实现Chris Penner的代码时遇到了问题 具体而言,在以下代码中: data Stream a = a :> Stream a deriving (Functor, Foldable) {-instance Functor Stream where f(x:>xs) = (f x):>(fmap f xs) -} fromlist :: [a] ->

我在这里尝试实现Chris Penner的代码时遇到了问题

具体而言,在以下代码中:

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) 

我试图为流数据类型编写一个实例声明,认为这样可以避免问题,但这也不起作用。如何解决我的问题?

默认情况下,Haskell无法生成可折叠and函子的实例。其中规定,它可以自动派生类型C的实例,给定:

C是Eq、Ord、Enum、Bounded、Show或Read中的一种。

您可以使用Glasgow Haskell编译器GHC的和语言扩展来启用以下功能:

{-# LANGUAGE DeriveFoldable, DeriveFunctor #-}

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
    fmap f (x:>xs) = f x :> fmap f xs

例如,还有其他扩展使其成为可遍历、泛型、提升等的实例。

默认情况下,Haskell无法生成可折叠和函子的实例。其中规定,它可以自动派生类型C的实例,给定:

C是Eq、Ord、Enum、Bounded、Show或Read中的一种。

您可以使用Glasgow Haskell编译器GHC的和语言扩展来启用以下功能:

{-# LANGUAGE DeriveFoldable, DeriveFunctor #-}

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
    fmap f (x:>xs) = f x :> fmap f xs

例如,还有其他扩展使其成为可遍历、泛型、Lift等的实例。

@Willem Van Onsem但是如果我拿出派生函子Foldable,我可以手动为它们编写实例吗?如果是这样的话,为什么我在上面的代码中注释掉的为Stream编写实例的尝试没有成功?@user65526:因为Functor提供了fmap函数,所以您没有编写fmap fx:>xs=…,但是fx:>xs=…@Willem Van Onsem啊,是的!谢谢:DeriveTraversable同时表示DeriveFunctor和DeriveFoldable,因此它是一个很好的一站式服务。@user65526值得注意的是,编译器在错误消息中告诉您如何修复它。我意识到在这种情况下,你还没有必要的背景来理解它,但在将来要记住这一点。编译器消息通常非常好。@Willem Van Onsem但是如果我拿出派生函子,Foldable,我可以手动为它们编写实例吗?如果是这样的话,为什么我在上面的代码中注释掉的为Stream编写实例的尝试没有成功?@user65526:因为Functor提供了fmap函数,所以您没有编写fmap fx:>xs=…,但是fx:>xs=…@Willem Van Onsem啊,是的!谢谢:DeriveTraversable同时表示DeriveFunctor和DeriveFoldable,因此它是一个很好的一站式服务。@user65526值得注意的是,编译器在错误消息中告诉您如何修复它。我意识到在这种情况下,你还没有必要的背景来理解它,但在将来要记住这一点。编译器消息通常非常好。