Haskell 需要帮助理解流

标签 haskell functional-programming stream read-eval-print-loop ghci

我有这些功能的代码:

  1. 从给定的流中创建一个无限列表;
  2. 为给定的迭代函数和起始流元素(种子)创建一个流;
  3. 将两个流合并为一个,以便它们的元素交错。

代码如下:

data Stream a = Cons a (Stream a)

streamToList :: Stream a -> [a]
streamToList (Cons x xs) = x : streamToList xs

streamIterate :: (a -> a) -> a -> Stream a
streamIterate f x = Cons x (streamIterate f (f x))

streamIterLeave :: Stream a -> Stream a -> Stream a
streamIterLeave (Cons x xs) ys = Cons x (streamIterLeave ys xs)

现在我遇到的问题是我不知道如何在 ghci 上检查这段代码。更具体地说,如何将流输入命令行?

例如,我尝试了 streamToList [1,2,3]streamToList (1,2,3); streamToList 1,2,3 但它们似乎都不起作用。

非常感谢您的帮助!

最佳答案

几种方式。最简单的就是使用 undefined:

> take 2 $ streamToList $ Cons 1 $ Cons 2 undefined
[1,2]

您可以在提示符下定义命名流,

> let { one = Cons 1 two ; two = Cons 2 one } 

或者多行输入,

> :{
| one = Cons 1 two
| two = Cons 2 one
| :}

> take 5 $ streamToList one
[1,2,1,2,1]

您可以使用您的 streamIterate,如评论中所示,或使用 foldr 从列表中创建您的流,

> take 5 $ streamToList $ streamIterate (+1) 0
[0,1,2,3,4]
> listToStream xs = foldr Cons undefined xs
> intS = listToStream [1..]
> take 5 $ streamToList intS 
[1,2,3,4,5]

定义了listToStream,你可以进一步轻松定义

> mapStream f s = listToStream . map f . streamToList $ s
> intsStream = x where { x = Cons 1 $ mapStream (1+) x }
> take 5 $ streamToList intsStream
[1,2,3,4,5]
> zipStr s1 s2 = listToStream $ zip (streamToList s1) (streamToList s2)
> zipStrWith f s1 s2 = mapStream (uncurry f) (zipStr s1 s2)
> addStreams s1 s2 = zipStrWith (+) s1 s2
> fibS = let {a = Cons 0 b; b = Cons 1 c; c = addStreams a b} in a
> take 15 $ streamToList fibS
[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377]

等等等等等


作为dfeuer在评论中提到,上面的 listToStream 有点虚假——它允许将无效(即有限)列表作为其参数。可以在 REPL 上玩它,但一般情况下不行。

通过定义

> :{ 
| (+++) :: [a] -> Stream a -> Stream a
| xs +++ ys  =  foldr Cons ys xs
| :}

允许我们定义流

> good = [1..] +++ undefined
> bad = [1..10] +++ undefined

问题在哪里(如果存在)会更加明显。

关于Haskell 需要帮助理解流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70317203/

相关文章:

haskell - MultiParamTypeClasses - 为什么这个类型变量不明确?

c# - 当 BufferBlock 为空时,Async StreamWriter Loop 停止写入

Node.js Streams on(end) 在异步 on(readable) 完成之前完成

java - 如何通过socket InputStream发送XML数据

haskell - 象牙色 : how to use the ivory-hw package

json - 为什么 Aeson 将 () 编码为空数组?

haskell - ifB 在reactive-banana 中的实现

functional-programming - 对于纯粹的、函数式的、热切评估的语言,垃圾收集器可以安全地做出哪些假设?

python - 跨多个链式函数的 namedTuples 定义

python - 函数式 python 编程和条件