【问题标题】:Show matrix function in haskell在haskell中显示矩阵函数
【发布时间】:2017-03-01 23:27:34
【问题描述】:

我刚开始使用 Haskell 学习函数式编程,在下面的案例中我需要你的帮助。

这个想法是通过以下方式使用 show 函数显示一个矩阵:

> Mat [[1,2,3],[4,5,6]]
  1 2 3
  4 5 6

我已经有实现上述结果的建议解决方案,但我不是特别了解。

data Mat a = Mat {mrows :: [[a]]}
instance (Show a) => Show (Mat a) where
     show  =  unlines . map (unwords . map show) . mrows

我在互联网上搜索了这部分Mat {mrows :: [[a]]},但找不到任何有用的答案。为什么我们不能将其声明为Mat [[a]]

另外,最后一行究竟是如何实现上述结果的。如果答案太明显,我很抱歉,但我真的刚刚开始学习 Haskell。

【问题讨论】:

    标签: haskell


    【解决方案1】:

    其实没问题——如果你愿意,你可以这样声明

    data Mat a = Mat [[a]]
    

    那么你只需要稍微改变一下显示实例声明

    instance (Show a) => Show (Mat a) where
         show (Mat x) = unlines $ map (unwords . map show) x
    

    编辑

    另一种方法有一些好处:

    如果您想获得更高的性能,可以将 data 关键字更改为 newtype

    此外,如果您想断言此列表列表仅包含相同大小的列表 - 您可以导出构造函数 Mat,但提供“智能”构造函数 mat :: [[a]] -> Maybe (Mat a),例如:

    mat x = if  (length $ nub $ map length x) <= 1) then Just x else Nothing
    

    但使用后一种方法,如果您导出 mrows,您仍然可以提取 [[a]] 部分

    module Mat (Mat, mrows, mat) where ...
    

    将隐藏Mat 构造函数,但将Mat 的类型导出到哪里

    module Mat (Mat(..), mat) ...
    

    将导出所有内容

    编辑2

    AAAA 另一件事 - 如果您有一个包含多个记录的类型,请说

    data Pirate = Pirate { head :: HeadThing
                         , rightArm :: ArmThing
                         , leftArm :: ArmThing
                         , rightLeg :: LegThing
                         , leftLeg :: LegThing}
    
    data ArmThing = ...
    data HeadThing = ...
    data LegThing = ...
    

    您可以使用记录语法更新一个(或多个“成员”) - 即

    redBeard :: Pirate
    redBeard = blackbeard {head = RedBeard, rightArm = Hook}
    

    【讨论】:

    • 感谢您的回复!如果没有问题,能否解释一下这两种方法的区别?
    • @JohnStef 阅读haskell中的数据声明可能对您更有用
    【解决方案2】:
    data Mat a = Mat {mrows :: [[a]]}
    

    这是 Haskell 的“记录语法”。 (这是您要搜索的术语。)上述声明与

    相同
    data Mat a = Mat [[a]]
    

    不同之处在于第二个声明了一个Mat 构造函数,其中包含[[a]] 类型的“未命名”字段,第一个命名字段mrows。特别是,这会自动定义一个函数

    mrows :: Mat a -> [[a]]
    

    “解包”Mat 构造函数。您还可以在模式中使用名称 mrows,但这通常对于具有 数十个 字段而不只是一个字段的构造函数更有用。

    一个命名字段也总是可以使用未命名的语法来引用,所以命名的版本完成了未命名的版本所做的所有事情,而且还有更多。

    【讨论】:

      猜你喜欢
      • 2011-02-04
      • 1970-01-01
      • 2012-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-11
      • 1970-01-01
      相关资源
      最近更新 更多