两种流类型之间的转换

Max*_*lve 1 haskell type-conversion isomorphism

我有一个关于在Haskell中转换两种数据类型的问题.

请考虑以下两种数据类型

data Stream a = Cons a (Stream a)

data Stream2 a = ST {shead :: a, stail :: Stream2 a}
Run Code Online (Sandbox Code Playgroud)

Q2:写

sToS2 :: Stream a -> Stream2 a

s2ToS :: Stream2 a -> Stream a
Run Code Online (Sandbox Code Playgroud)

在两个流表示之间进行转换

我遇到麻烦的第一件事是Stream数据类型,我们可以看到这是一个递归数据类型,但没有基本情况,这让我想知道这是否有点无限以及如何创建流数据类型.此外,Stream2的构造函数以记录语法给出,其中一个字段也是Stream2类型.我知道有一个类似于时间的问题

data Ab = A | B
data Cd = C | D

fromAb :: Ab -> Cd
fromAb A = C
fromAb B = D

toAb :: Cd -> Ab
toAb C = A
toAb D = B
Run Code Online (Sandbox Code Playgroud)

但我不确定如何将这个问题的答案应用到我特别的困惑中.

Chr*_*tin 6

没有基本情况,这让我想知道这是否有点无限

它是!

以及我如何创建一个流

递归!Haskell是非严格的,所以这没问题.看吧:

successors :: Num a => a -> Stream a
successors start = Cons start $ successors $ start + 1

?> case successors 1 of Cons _ (Cons _ (Cons x _)) -> x
3
Run Code Online (Sandbox Code Playgroud)

Stream2的构造函数以记录语法给出,其中一个字段也是Stream2类型

确实.除了使用记录糖之外,Stream2类型相同(或者更准确地说,是同构的)Stream.我们可能会对事情进行一些调整,以使相似之处更加明显:

data Stream  a = Cons            a           (Stream  a)
data Stream2 a = ST   { shead :: a, stail ::  Stream2 a }
--   [  1  ]     [ 2 ]          [3]           [   4   ]
Run Code Online (Sandbox Code Playgroud)
  1. 类型
  2. 类型的唯一构造函数
  3. 第一个构造函数参数的类型
  4. 第二个构造函数参数的类型

您在编写转换时可以忽略记录语法.

sToS2 :: Stream  a -> Stream2 a
s2ToS :: Stream2 a -> Stream  a

sToS2 (Cons x xs) = ST   x $ sToS2 xs
s2ToS (ST   x xs) = Cons x $ s2ToS xs
Run Code Online (Sandbox Code Playgroud)