haskell - 了解数据类型、类型类的签名,并使数据类型成为类型类的实例
问题描述
一直在阅读为伟大的利益而学习 Haskell!并且在理解实例和种类方面遇到了很大的麻烦。
Q1: 那么类型t
inTofu t
是一个带有 kind 签名的函数(* -> (* -> *)) -> *
?tofu
is的整体签名* -> *
,不是吗?因为(* -> *) -> *
结果*
和所以(* -> (* -> *)) -> *
Q2:当我们要创建Frank a b
typeclass 的实例时Tofu t
,数据类型Frank a b
也必须和 具有相同的种类t
。这意味着 kind of a
is *
, b
is * -> *
, b a
which will be (* -> *) -> *
which results in *
。那是对的吗?
Q3:x
intofu x
表示j a
两者都有*
. Frank
用它的种类(* -> (* -> *)) -> *
应用在x
. 但我不确定如何呈现j a
asx
将区分x
in tofu x
which isj a
和x
in Frank x
which is a j
。
我对在数据类型或类(例如:b
inFrank a b
或t
in Tofu t
)中有一个函数的想法有点陌生,这有点令人困惑
我把链接留在这里,因为引用会使帖子看起来不必要的长。关联
class Tofu t where
tofu :: j a -> t a j
data Frank a b = Frank {frankField :: b a}
instance Tofu Frank where
tofu x = Frank x
解决方案
Q1:
所以 Tofu t 中的类型 t 充当具有种类签名 (* -> (* -> *)) -> * 的函数?
t
的种类是* -> (* -> *) -> *
,或者更明确地* -> ((* -> *) -> *)
说,不是(* -> (* -> *)) -> *
。
豆腐的整体签名是* -> *,不是吗?
tofu
没有种类签名,只有类型构造函数有;它的类型是*
. 它的参数和结果的类型也是如此。任何功能都一样。
Q2:您从一个错误的假设开始:instance Tofu Frank
使Frank
类型构造函数成为 的实例Tofu
,而不是Frank a b
。因此,Frank
它必须与 具有相同的种类t
,而不是Frank a b
(具有种类*
)。
ba 这将是 (* -> *) -> *
不,b a
是b
kind * -> *
to a
of kind*
的应用,所以应用有 kind *
。就像b
是 type 的函数x -> y
,并且a
是 type 的值x
,b a
会有 type y
,而不是(x -> y) -> x
:只是 replacex
和y
by *
。
问题 3:
豆腐x中的x代表ja
“有类型”,而不是“代表”。
因为两者都有 *
x
没有种类,因为它不是类型。
Frank 及其类型 (* -> (* -> *)) -> * 应用于 x
不,在
tofu x = Frank x
它是应用于的Frank
数据构造函数x
,而不是类型构造函数。这是一个带有签名的函数b a1 -> Frank a1 b
(重命名a
,以免与tofu
's 混淆)。所以b ~ j
和a1 ~ a
。
推荐阅读
- angular - “void”类型上不存在属性“profile”
- node.js - 文件上传适用于邮递员,但不适用于 angular2
- javascript - WordPress AJAX 表单/jQuery 未在后端更新用户元数据
- boost - gdb 从不同位置查找标头
- mysql - creating primary key on two columns which are unique together
- header - 错误要求:Volley 400
- html - Bootstrap 4 columns not working
- dhis-2 - DHIS2 and mysql?
- amazon-web-services - Amazon Cloudfront 和 EC2 重定向设置
- javascript - onchange 事件后如何保持选定值不变?