繁体   English   中英

Haskell数据类型函数参数

[英]Haskell data type function parameter

对于参数的数据类型,Haskell中的函数定义中的括号有什么意义。

例如:

doStuff Name -> Age -> String
doStuff (NameConstr a) (AgeConstr b) = "Nom: " ++ a ++ ", age: " ++ b

预先在某处定义以下内容:

data Name = NameConstr String
data Age = AgeConstr Integer

功能参数a和b是否可以在这里取消对括号的需要?

仅供参考,我正在努力:

我似乎无法掌握这个更精细的细节。

没有括号,该函数将被视为具有四个参数。 我想不出一个反例,即省略括号会导致含糊不清。

如果需要,您可以按如下方式重新定义类型:

data Name = NameConstr { getName :: String  }
data Age  = AgeConstr  { getAge  :: Integer }

这样你的功能就可以变成:

doStuff n a = "Nom: " ++ getName n ++ ", age: " ++ show (getAge a)

(修复了最后一部分; a是一个Integer ,不能连接成一个字符串)

实际上,有可能为(甚至嵌套的)模式解析简单的语法而根本没有parens。 假设这样一个:

<PAT>  ::= <WILDCARD> | <VAR> | <CON0> | <CON1> <PAT> | <CON2> <PAT> <PAT> ...
<VAR>  ::= <LNAME>
<CON*> ::= <UNAME>
<WILD> ::= "_"

其中LNAME是以小写字母开头的名称,UNAME以大写字母开头。 解析时我们应该查找构造函数名称,以便我们找到它的arity。 然后我们可以使用arity信息解析构造函数字段。 但是这种查找可能会使解析本身变得复杂化并减慢其速度。 Haskell具有更复杂的模式(视图模式,“作为”模式,记录,具有任意固定性的中缀构造函数等)并且省略parens可能导致模糊性。

虽然还有另一个原因不这样做。 请考虑以下代码:

data Bar = Bar Int
data Foo = Foo Int

libFunction Foo a Bar b = a + b
someUse bar foo = libFunction foo bar

接下来想象我们稍微更改数据类型:

data Bar = Bar
data Foo = Foo Int Bar Int

修改后的代码可能仍然存在类似问题,但该功能将不符合我们的预期。 虽然不是现实世界的例子。 而且由于Haskell有类型类,因此很难找到出错的地方。

换句话说:我们可以放松错误消息的质量,而且parens可以防止我们在更改后出现意外行为。

它有点傻,但在这种情况下,实际上有一种方法可以避免使用括号:

doStuff :: Name -> Age -> String
NameConstr a `doStuff` AgeConstr b = "Nom: " ++ a ++ ", age: " ++ b

这与定义中缀运算符的方式完全相同,并且使用反引号作为infix-ify非运算符标识符在将其定义为应用时也同样有效。

不过,我不推荐使用你不希望在backtick-y中缀风格中使用的函数实际执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM