微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Haskell 类型构造函数“只是”一个函数吗?

如何解决Haskell 类型构造函数“只是”一个函数吗?

我正在学习“Haskell Programming from first原则”并发现了一个练习,询问以下[此处稍微编辑的代码]是否有效:

module Test where

type Subject = String
type Verb = String
type Object = String

data Sentence = 
  Sentence Subject Verb Object
  deriving (Eq,Show)

a1 = Sentence "I" "like" "cheese"
a2 = Sentence "I" "scream"

我最初的预期是代码会失败,因为在 a2 的定义中,Sentence 只有两个参数。但是发现 GHCi 很乐意加载模块。我做了一点实验,发现我现在可以打字

a3 = a2 "icecream"

a3(输入到 GHCi 中)将打印 Sentence "I" "scream" "icecream"。此外,如果我查询 a2 的类型,我会得到 a2 :: Object -> Sentence。因此,如果我理解正确的话,a2 的行为与部分应用的函数完全一样。

因此问题是:类型构造函数在所有情况下是否真的只是一个函数(返回类型值) - 与“普通”函数的区别仅在于它必须以大写字符开头?

解决方法

首先,您在这里谈论的是数据构造函数,而不是类型构造函数。该示例恰好包含(空)类型构造函数 Sentence 和三元数据构造函数 Sentence。明确哪个是哪个:

data SentenceTC = SentenceDC Subject Verb Object

SentenceTC 是类型构造函数,SentenceDC 是数据构造函数。

所以,问题是:

SentenceDC 只是一个函数吗?

答案是,它一个函数,而不是“只是”一个函数。它特别是一个 injective function,即每个参数组合都会导致不同的结果。因此,始终可以从结果 SentenceTC 值推断出它是哪些参数。这就是当您在构造函数上模式匹配时会发生的情况。

a1Verb :: Verb
a1Verb = case a1 of
    Sentence _ v _ -> v

这对于一般的函数是不可能的,比如

n' :: Int
n' = abs n
 where n = -3

nNew :: Int
nNew = case n' of
   abs n -> n   -- error,`abs` can not be used as a pattern match

这也没有意义,因为实际上有两个不同的数字,其 abs 等于 n'(即,-33)。

但是,是的,SentenceDC 是一个函数,你可以用它做任何你可以用其他 String -> String -> String -> SentenceTC 类型的函数做的事情。但反过来也一样:并非您可以使用数据构造函数执行的所有操作也可以使用相同类型的通用函数来完成。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。