里面的函数letnotNum

我有这些

data Fruit = Peach | Apple | Pear | Lemon | Fig deriving (Show,Eq)
data FTree = Bud | Split FTree FTree | Flat Fruit FTree deriving (Show,Eq)

这意味着计算输入的水果类型的出现次数

ftreeFOccurs cft ft =
  let ftFO Bud = 0
      ftFO (Flat frt ft) = if (frt == cft) then (1 + (ftFO ft)) else (ftFO ft)
      ftFO (Split ft1 ft2) = (Split (ftFO ft1) (ftFO ft2))
  in ftFO ft

这将是一棵典型的树

Split (Split Bud Bud) (Flat Fig (Flat Lemon (Flat Apple Bud)))

但是当我提交时,ftreeFOccurs我收到此错误

No instance for (Num FTree) arising from the literal `0'
    * In the expression: 0
      In an equation for `ftFO': ftFO Bud = 0

然而,类似的功能,

ftreeHeight Bud = 0
ftreeHeight (Flat frt ft) = 1 + ftreeHeight ft
ftreeHeight (Split ft1 ft2) = deeper (1 + ftreeHeight ft1) (1 + ftreeHeight ft2)
                              where deeper t1 t2 = if (t1 >= t2) then t1 else t2

作品。这是来自The Little MLer的 SML 问题的翻译,其中该occurs函数有一个 2 元组参数,其中水果和树通过递归进行......这似乎不像 Haskell 方式。但是我不确定为什么在 a 中有一个函数let会产生这种差异。

回答

在您的函数中添加一些类型,以便 Haskell 可以更好地提示您出错的地方。如果没有类型,它将对您的意思进行假设,直到遇到矛盾为止,您将不知道哪个假设是错误的。

在这种情况下,令人困惑的是有时ftFO返回一个数字,有时它返回一个FTree. 这不是你想要的,但如果 Haskell 假设它FTree可以理解为一个数字,那么在技术上是允许的。所以 Haskell 继续这个想法一段时间,直到它发现没有人说过如何解释FTree为一个数字。

  • Much better would be `ftFO (Split ft1 ft2) = ftFO ft1 + ftFO ft2`. Right...

以上是里面的函数letnotNum的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>