Haskell漂亮打印二维列表(失败说明)
Pretty-Printing 2D List in Haskell (Explanation of Failure)
Answers exist for how to pretty-print in Haskell, including how to do it with packages,但这更多的是关于为什么我的第一种方法失败的问题。
给定一个 w = [r,r1,r2]
形式的二维列表,其中 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 中递归打印一个不确定长度的二维列表?
在您的情况下,类型应为 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)
*其实也可以打底,那是另外一回事了
Answers exist for how to pretty-print in Haskell, including how to do it with packages,但这更多的是关于为什么我的第一种方法失败的问题。
给定一个 w = [r,r1,r2]
形式的二维列表,其中 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 中递归打印一个不确定长度的二维列表?
在您的情况下,类型应为 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)
*其实也可以打底,那是另外一回事了