Answers exist 如何在Haskell中进行漂亮打印,包括如何使用packages进行打印,但这更像是一个问题,为什么我的第一种方法失败了。
给定w = [r,r1,r2]
形式的2D列表,其中w,r各自的数据类型w::W
,r::R
(示例的简单变量,而不是我的实际命名约定):
data X = Y | Z
deriving (Eq, Show)
data R = [X]
deriving (Eq, Show)
data W = [R]
deriving (Eq, Show)
为什么以下任何一种方法都不起作用? (我完全清楚这将包括括号和逗号,这不是问题)
ppR :: R -> IO ()
ppR = putStrLn . show
和
ppW :: W -> IO W (?)
ppW (w:[]) = ppR w
ppW (w:ws) = ppR w >> ppW ws
或
ppW :: W -> IO W (?)
ppW (w:[]) = putStrLn . show w
ppW (w:ws) = putStrLn . show w >> ppW ws
我不太清楚ppW
的类型,我还在学习。除了我对Haskell处理不纯函数的天真(缺乏)理解之外,我还因为第二种ppW类型检测方法(没有提供类型)而受阻。
为什么这种方法不起作用?你能否在Haskell中以递归方式打印不确定长度的2D列表?
答案 0 :(得分:2)
在您的情况下,类型应为ppW :: W -> IO ()
。 ()
(发音为" unit")是一种只能有一个*值的类型 - 即()
。所以IO ()
是一个IO动作,因此没有给出任何值(它等同于C,C ++或Java的void函数)。
以下是一些应该编译的代码:
data X = Y | Z
deriving (Eq, Show)
type R = [X]
type W = [R]
ppR :: R -> IO ()
ppR = putStrLn . show
ppW :: W -> IO ()
ppW (w:[]) = ppR w
ppW (w:ws) = ppR w >> ppW ws
如果您对类型有任何问题,可以随时使用ghci来确定任何函数的类型。或者您可以简单地查看您正在使用的函数类型:
putStrLn :: String -> IO()
(>>) :: IO a -> IO b -> IO b -- this is not exactly what ghci would tell you.
编辑:
在我收录的代码中,我使用type
代替data
。 type
定义了一个类型同义词(它类似于C / C ++ typedef)。使用它们比使用data
更容易 - data
要求您明确写出构造函数的名称,因此您将拥有:
data R = R [X]
ppR :: R -> IO ()
ppR (R r)= putStrLn (show r)
*实际上它也可以是底部,但这是一个不同的故事。