在haskell中显示矩阵函数

时间:2017-03-01 23:27:34

标签: haskell

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

我们的想法是使用show函数以下列方式显示Matrix:

> 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。

2 个答案:

答案 0 :(得分:6)

实际上没问题 - 如果你愿意,你可以这样宣布

data Mat a = Mat [[a]]

然后你只需稍微改变show instance声明

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

修改

另一种方法有一些好处:

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

此外,如果你想声明这个列表列表只包含相同大小的列表 - 你可以导出构造函数Mat但是提供一个'智能'构造函数{{1喜欢:

mat :: [[a]] -> Maybe (Mat a)

但是使用后一种方法,如果导出mat x = if (length $ nub $ map length x) <= 1) then Just x else Nothing

,您仍然可以提取[[a]]部分
mrows

会隐藏module Mat (Mat, mrows, mat) where ... construcor,但会导出Mat的类型

Mat

将导出所有内容

EDIT2

AAAA另一件事 - 如果你有一个有多个记录的类型说

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

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

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

data ArmThing = ...
data HeadThing = ...
data LegThing = ...

答案 1 :(得分:2)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>
<xsl:output omit-xml-declaration="yes" indent="yes"/>


<xsl:template match="/">
<xsl:apply-templates select="//charac[charactername='print' or charactername='comp']" />
</xsl:template>


<xsl:template match="charac">
     <e1edl1>
         <at><xsl:value-of select="charactername" /></at>
         <rt><xsl:value-of select="charactervalue" /></rt>
     </e1edl1>
</xsl:template>


</xsl:stylesheet>

这是Haskell&#34;记录语法&#34;。 (这是您要搜索的术语。)上述声明与

相同
data Mat a = Mat {mrows :: [[a]]}

不同之处在于第二个声明data Mat a = Mat [[a]] 构造函数带有&#34;未命名的&#34;类型Mat的字段,第一个命名字段[[a]]。特别是,这自动定义了一个函数

mrows

&#34; unwraps&#34; mrows :: Mat a -> [[a]] 构造函数。您也可以在模式中使用名称Mat,但这对于数十字段的构造函数通常更有用,而不仅仅是一个。

也可以使用未命名的语法来引用命名字段,因此命名版本会执行未命名版本所做的所有操作以及更多内容。