【发布时间】:2015-11-17 18:33:07
【问题描述】:
我是 Haskell 的新手,对以下行为感到困惑:
我有一个函数,叫做 dealWithIt。它看起来像这样:
dealWithIt :: (Show a) => [a] -> String
dealWithIt = foldl f ""
where f memo x = memo ++ (show x)
一切都好,它按预期工作,它获取一个可显示的列表并将它们连接成一个字符串。
据我所知,我是否明确指定接收的参数并不重要,只要它可以传递给底层函数链即可。这意味着以下两个定义应该是等价的:
dealWithIt xs = foldl f "" xs
dealWithIt = foldl f ""
到目前为止一切顺利。假设我现在想通过模式匹配添加一个特殊情况:
dealWithIt [] = "Empty list :("
这就是事情变得奇怪的地方。如果我没有明确指定 xs 参数,我会收到以下错误:
Equations for ‘dealWithIt’ have different numbers of arguments
我可以接受它,但我真的很感兴趣,为什么 Haskell 无法检测到正在发生的事情并报告错误,即使两个变体都采用一个参数?
【问题讨论】:
-
dealWithIt = foldl f ""已经指定了所有可能参数的行为。用另一个参数再次定义它有什么意义? -
添加特殊情况与处理所有可能的参数无关。
-
编译器抛出的错误信息说清楚了。这些是不同的功能。比较他们的签名。如果你需要处理 special 参数,你可以使用参数模式匹配但保持相同的类型。或使用警卫,或 if/case 条件。
-
但这正是让我感到困惑的地方,因为我的函数的两个变体具有相同的签名并接受相同类型的单个参数。那么错误来自哪里?
-
这是一个非常合理的问题。编译器当然可以用更少的参数扩展方程。我相信这只是一个设计选择来禁止它,因此在意外忘记参数而不是神秘类型错误时提供更好的错误消息。当然,这种设计可以反对——这是一个偏好问题。
标签: haskell