从ADT创建无限列表

时间:2016-01-20 16:52:18

标签: haskell

在Haskell,

 > a = [1,1..]

创建一个无限列表。现在我有以下

data Subunit = O | P deriving (Eq, Show)           

如果我这样做

b :: [Subunit]                                                                   
b = take 6 [P,P..]  

我得到以下内容:

 parse error on input ‘]’

为什么会失败?我需要添加什么才能创建无限列表?

5 个答案:

答案 0 :(得分:11)

好的抓住!确实错了......

> take 10 [P, P..]

<interactive>:6:16: parse error on input ‘]’

......但这不是

> take 10 [P, P ..]   -- one more space
[P,P,P,P,P,P,P,P,P,P]

为什么空白是重要的?因为否则语法与模块前缀名称重叠,其形式为Module.name。例如,以下是访问.的运算符Prelude的方式。

> :t (Prelude..)
(Prelude..) :: (b -> c) -> (a -> b) -> a -> c
> :t succ Prelude.. succ   -- infix use!
succ Prelude.. succ :: Enum c => c -> c

因此,P..来自模块.的{​​{1}},而P在列表枚举中正常工作。

(是的,这是语法的一个不幸的怪癖......)

答案 1 :(得分:3)

[n,n'..]enumFromThen的语法糖,因此您需要将您的类型设为Enum类型类的实例。

您还需要一个值,而不是值构造函数

\> data Subunit = O | P deriving (Eq, Show, Enum)
\> let a = P
\> take 6 [a,a..]
[P,P,P,P,P,P]

或(@@ sepp2k评论):

\> take 6 [P,P ..]
   --         ^ space
[P,P,P,P,P,P]

答案 2 :(得分:3)

作为替代behzads的答案你可以做到

b :: [Subunit]
b = take 6 $ repeat P

也是 - 这个不需要Enum

答案 3 :(得分:1)

您可以使用此行生成无限的ADT列表。

infiniteSubunit = P:infiniteSubunit

然后你可以按原样使用它。

b :: [Subunit]                                                                   
b = take 6 infiniteSubunit

答案 4 :(得分:1)

作为另一种选择,要执行您想要直接执行的操作,请使用

b :: [Subunit]
b = replicate 6 P