*.xlsx
收到错误
{-# LANGUAGE NamedFieldPuns #-}
data Factory = Factory { fId :: Int}
data Link = Link Int Int Double
hasLinkTo :: Factory -> Link -> Bool
hasLinkTo Factory{fId} (Link fId _ _) = True
我知道使用变量可以修复它,
• Conflicting definitions for ‘fId’ Bound at: <source.hs> In an equation for ‘hasLinkTo’
我想要求
例如:如果我想提取到节点hasLinkTo Factory{fId=a} (Link b _ _) = a == b
的链接,我想写这样的东西
i
有没有办法只使用非数字文字上的模式匹配来检查(==)?
connected :: Int -> Link -> (Int, Double)
connected i (Link i j d) = (j,d)
connected i (Link j i d) = (j,d)
工作正常。但上面的例子不会。
答案 0 :(得分:2)
用Factory{fId}
记录双关语只是GHC扩展到Factory{fId=fId}
的句法糖。这声明了一个名为fId
的变量,其值为fId
记录中名为Factory
的字段。
此外,模式匹配仅声明变量。它不允许您通过重复相同的名称来比较它们。考虑尝试比较平等:
eq a a = True
eq _ _ = False
这是一个尝试做同样事情的简单例子。但它不会编译。
以同样的方式,编译器会抱怨,因为在执行(Link fId _ _)
时声明了两个变量。这是不允许的。相反,您需要使用另一个名称并明确比较两者:
hasLinkTo Factory{fId} (Link fInd' _ _) = fId == fId'
答案 1 :(得分:2)
Haskell只允许使用线性模式,每个变量最多只能出现一次。我相信这是一个刻意的设计选择。从理论上讲,
case e1 of C x x y -> e2 ; ...
可以自动翻译为
case e1 of C x1 x2 y | x1==x2 -> e2 ; ...
这意味着非线性模式需要对非线性变量类型进行额外的Eq
约束。此外,可以认为程序员可能会意外地错误地重用变量,如果我们允许非线性模式,这将被忽略并导致意外的语义。
可能Haskell的设计者认为在模式中添加| x1==x2
并不是太麻烦,并且使意图更加明确。
但是,对于数字文字,他们保留了这种翻译。模式
case e1 of K 0 y z -> e2 ; ...
转换为
case e1 of K x y z | x==0 -> e2 ; ...
并且需要Eq
。由于0
不是变量,我们不再存在非线性模式的问题。
无论如何,惯用的方法是在非线性模式中添加| x1==x2
等守卫。
目前您不能仅使用模式匹配。