2016-01-20 45 views
4

的在Haskell,创建无限列表出来ADT

> a = [1,1..] 

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

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

如果我去做

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

我得到如下:

parse error on input ‘]’ 

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

回答

9

尼斯赶上!事实上,它的错误了......

> 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..是从模块P.,而P ..在列表中列举正常工作。

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

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] 
+0

“你也需要一个值,而不是一个值构造器“'[P,P ..]'工作得很好。一个空值构造函数*是一个值。 – sepp2k

+0

@ sepp2k你是对的。 '''之前需要额外的空间。没有它[P,P ..]错误。 –

1

您可以使用此行来生成ADT的无限名单。

infiniteSubunit = P:infiniteSubunit 

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

b :: [Subunit]                 
b = take 6 infiniteSubunit 
+2

也可以使用'infiniteSubunit = fix(P:)'来代替自己做循环。 – amalloy

3

,以替代behzads回答,你可以做

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

太 - 这一个不需要Enum

1

作为另一种选择,要做到什么样子,你想直接做的,使用

b :: [Subunit] 
b = replicate 6 P