Haskell 两种流类型之间的转换

Haskell 两种流类型之间的转换,haskell,type-conversion,isomorphism,Haskell,Type Conversion,Isomorphism,关于Haskell中两种数据类型之间的转换,我有一个问题 考虑以下两种数据类型 data Stream a = Cons a (Stream a) data Stream2 a = ST {shead :: a, stail :: Stream2 a} 问题2:写作 sToS2 :: Stream a -> Stream2 a s2ToS :: Stream2 a -> Stream a 在流的两种表示形式之间进行转换 我遇到的第一个问题是流数据类型,我们可以看到这是一个递归

关于Haskell中两种数据类型之间的转换,我有一个问题

考虑以下两种数据类型

data Stream a = Cons a (Stream a)

data Stream2 a = ST {shead :: a, stail :: Stream2 a}
问题2:写作

sToS2 :: Stream a -> Stream2 a

s2ToS :: Stream2 a -> Stream a
在流的两种表示形式之间进行转换

我遇到的第一个问题是流数据类型,我们可以看到这是一个递归数据类型,但没有基本情况,这让我想知道这是否是无限的,以及如何创建流数据类型。此外,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
但我不确定如何将这个问题的答案应用到我的困惑中

没有基本情况,这让我怀疑这是否是无限的

是的

以及如何创建一个流

递归地!Haskell不严格,所以这没问题。瞧:

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

λ> case successors 1 of Cons _ (Cons _ (Cons x _)) -> x
3
Stream2的构造函数以记录语法给出,其中一个字段也是Stream2类型

的确如此。除了使用记录糖外,
Stream2
类型与
Stream
相同(或者更准确地说,同构)。我们可以把事情排成一行,使相似之处在视觉上更加明显:

data Stream  a = Cons            a           (Stream  a)
data Stream2 a = ST   { shead :: a, stail ::  Stream2 a }
--   [  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
    
    没有基本情况,这让我怀疑这是否是无限的

    是的

    以及如何创建一个流

    递归地!Haskell不严格,所以这没问题。瞧:

    successors :: Num a => a -> Stream a
    successors start = Cons start $ successors $ start + 1
    
    λ> case successors 1 of Cons _ (Cons _ (Cons x _)) -> x
    3
    
    Stream2的构造函数以记录语法给出,其中一个字段也是Stream2类型

    的确如此。除了使用记录糖外,
    Stream2
    类型与
    Stream
    相同(或者更准确地说,同构)。我们可以把事情排成一行,使相似之处在视觉上更加明显:

    data Stream  a = Cons            a           (Stream  a)
    data Stream2 a = ST   { shead :: a, stail ::  Stream2 a }
    --   [  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
    

    感谢您的回复,我正在尝试实现两个函数sToS2::Stream a->Stream2 a s2ToS::Stream2 a->Stream a,在这两种数据类型之间进行转换。@我知道,这个答案正在进行中。请参阅最新编辑。感谢您的回复,Cons运算符是否可以用于非列表的数据类型?它是否可以像x是流数据类型的头,xs是流数据类型的尾一样读取?对不起,我不理解这个问题。谢谢你的回答,我正在尝试实现两个函数sToS2::Stream a->Stream2 a s2ToS::Stream2 a->Stream a,在这两个函数中它在两个数据类型之间进行转换。@max12我知道,这个答案是一项正在进行的工作。请参阅最新编辑。感谢您的回复,Cons运算符是否可以用于非列表的数据类型?它是否可以像x是流数据类型的头,xs是流数据类型的尾一样读取?对不起,我不理解这个问题。