【问题标题】:Pretty-Printing 2D List in Haskell (Explanation of Failure)Haskell 中漂亮的打印 2D 列表(失败的解释)
【发布时间】:2015-01-20 17:36:04
【问题描述】:

Answersexist 用于如何在 Haskell 中进行漂亮打印,包括如何使用 packages 进行打印,但这更多是关于为什么我的第一种方法失败的问题。 p>

给定一个w = [r,r1,r2] 形式的二维列表,其中 w,r 分别是 w::Wr::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 列表吗?

【问题讨论】:

    标签: haskell io pretty-print


    【解决方案1】:

    在您的情况下,类型应该是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 而不是datatype 定义了一个类型同义词(它就像 C/C++ typedef)。使用它们比使用 data 更容易 - data 要求您明确编写构造函数的名称,因此您将:

    data R =  R [X]
    
    ppR :: R -> IO ()
    ppR (R r)= putStrLn (show r)
    

    *实际上它也可以是底部,但那是另一回事。

    【讨论】:

    • 我认为这值得解释为什么使用type 而不是data。 (RW 没有构造函数)
    • 知道我实际上并没有太远,这让我松了一口气。我会在回家后立即将其标记为已接受并亲自尝试。
    猜你喜欢
    • 2011-01-02
    • 2016-07-07
    • 2020-11-12
    • 2018-05-27
    • 2013-11-08
    • 2014-05-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-04
    相关资源
    最近更新 更多