在Haskell,
> a = [1,1..]
创建一个无限列表。现在我有以下
data Subunit = O | P deriving (Eq, Show)
如果我这样做
b :: [Subunit]
b = take 6 [P,P..]
我得到以下内容:
parse error on input ‘]’
为什么会失败?我需要添加什么才能创建无限列表?
答案 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