Haskell中链表的基本操作

时间:2017-06-15 18:35:50

标签: haskell linked-list

我正在尝试为Haskell中的链表编写一些基本的列表操作,但我可以用这一手。我想将一个列表附加到另一个列表但它根本不起作用,这是我的代码:

data ML a = E | L a (ML a) deriving (Show)

myList = (L 1 (L 2 (L 3 (L 4 E))))

myHead :: ML a -> a
myHead E = error "empty list"
myHead (L a _) = a

myTail :: ML a -> ML a
myTail E = error "empty list"
myTail (L _ a) = a

myAppend :: ML a -> ML a -> ML a
myAppend E a = a
myAppend (x L xs) ys = x L (xs myAppend ys)

我还有一个关于如何将此列表显示为类似于" 1,2,3"的字符串的问题。我有一个函数,它显示为像[1,2,3]这样的列表,但不是字符串。

toString :: ML a -> [a]
toString E = []
toString (L a l) = a:(toString l)

1 个答案:

答案 0 :(得分:3)

我认为基本问题出在最后一行:

myAppend :: ML a -> ML a -> ML a
myAppend E a = a
myAppend (x L xs) ys = x L (xs myAppend ys)

构造函数是L,在Haskell中,通常会将构造函数写在其参数之前,如:

myAppend :: ML a -> ML a -> ML a
myAppend E a = a
myAppend (L x xs) ys = L x (myAppend xs ys)

现在应该可以了。

关于第二个问题:toString ML a -> [a]。实际上 [a]是一个列表,而不是String(好吧,StringChar的列表:type String = [Char] ),并猜测:Haskell中的列表是一个链表。这意味着您的toString :: ML a -> [a]实际上更像是toList

如果你想用String写一些东西,那就意味着元素应该有文字表示。您可以使用类型约束来编写它,例如Show a =>。现在签名是:toString :: Show a => ML a -> [String]

我们可以将a的列表转换为文本表示形式,map将所有元素ping到其文本表示形式,并intercalate :: [a] -> [[a]] -> [a]例如使用逗号,例如:< / p>

import Data.List(intercalate)

toList :: ML a -> [a]
toList E = []
toList (L x xs) = x : toList xs

toString :: Show a => ML a -> String
toString = intercalate "," . map show . toList

或者我们可以自己实现这个功能&#34;:

toString :: Show a => ML a -> String
toString E = ""
toString (L x E) = show x
toString (L x xs) = show x++',' : toString xs