通过多行

时间:2016-12-12 18:39:12

标签: function haskell pattern-matching

我希望用这种漂亮,干净的方式来描述具有函数和模式匹配的对象的属性:

data Animal = Cat | Dog | Cow

isBig :: Animal -> Bool
isLoyal :: Animal -> Bool
-- many more possible properties, including complicated non-bools, methods, and whatnot


--- Describing Cat

isBig Cat = False
isLoyal Cat = False
--- more properties


--- Describing Dog

isBig Dog = False
isLoyal Dog = True
--- more properties


--- Describing Cow

isBig Cow = True
isLoyal Cow = False
--- more properties

但是,这会产生有关多个声明的错误。因为,显然,通过模式匹配的函数定义必须在连续的行中完成。

这是否表明我的方法是错误的,不像Haskell一样?或者它只是语言中的一个缺陷?或者我误解了什么?

2 个答案:

答案 0 :(得分:5)

这既不是语言中的缺陷,也不表明你的方法是错误的。这仅仅是一个句法限制,作为一个令人讨厌的设计决定的一部分,必须以某种方式做出。

限制的吸引力在于它意味着在阅读代码时,人们不必担心他们错过了部分值的定义,因为它分散在当前文件的远处。但它确实阻止了一些完美的逻辑组织代码方式,包括您当前正在尝试使用的方法。

我们不能同时拥有这两件事真是太可惜了!

可以考虑做这样的事情:

data Stats = Stats
    { isBig :: Bool
    , isLoyal :: Bool
    , -- ...
    }

stats :: Animal -> Stats
stats Cat = Stats
    { isBig = False
    , isLoyal = False
    }

答案 1 :(得分:2)

引用Section 4.4.3.1 of the Haskell Report

  

4.4.3.1功能绑定

     

函数绑定将变量绑定到函数值。变量x的函数绑定的一般形式是:

     

[函数绑定语法规范,涵盖多子句场景。]

     

请注意,定义函数的所有子句必须是连续的,并且每个子句中的模式数必须相同。 [...]

您注意到的限制是“定义函数的所有子句必须是连续的”。 Daniel Wagner的回答讨论了这一设计决策背后的可能原理。特别要强调的是,忘记与某个类型的构造函数相对应的子句是一个非常危险的错误,如果有可能以你建议的方式拆分条款,那么它将更容易实现(一个函数需要预计Animal将处理所有三种可能性。