小编sho*_*one的帖子

551
推荐指数
7
解决办法
19万
查看次数

如何将约束添加到类型构造函数

请考虑以下数据类型:

data Get (statusCode :: Nat)
Run Code Online (Sandbox Code Playgroud)

实际上,它是来自servant的简化类型构造函数,然后在类型级API中使用,如下所示:

type API = "users" :> Verb 'GET 200 '[JSON] [User]
Run Code Online (Sandbox Code Playgroud)

出于我们的目的,我们可以将API减少到

type API = Get 200
Run Code Online (Sandbox Code Playgroud)

现在,限制状态代码Nat是太松散了,允许定义不存在的HTTP状态代码:

type API = Get 999
Run Code Online (Sandbox Code Playgroud)

因此,问题:有没有办法限制可以应用于Get类型构造函数的自然集?

尝试了什么

为清楚起见,我将省略代码示例中的所有编译指示和导入.

另一种 statusCode

解决这个问题的一个明显方法是为状态代码定义一个单独的ADT,并使用它代替Nat利用数据类型提升.

data StatusCode = HTTP200 | HTTP201 | HTTP202
data Get (statusCode :: StatusCode)
Run Code Online (Sandbox Code Playgroud)

但是,这是一个重大变化,需要修改主要版本并重写所有用户的定义.我怀疑限制代码的好处是值得的.

DatatypeContexts

此扩展允许对我们的类型变量进行直接约束

data IsStatusCode statusCode => Get (statusCode :: Nat)
Run Code Online (Sandbox Code Playgroud)

但它要求用户将约束添加到他们的所有声明中.再次,一个突破性的变化.此外,DatatypeContexts已被弃用.

键入家庭

我们可以Get'使用类型族从下面的示例中有条件地创建,但由于某种原因,声明类型别名可以快速编译.为了得到一个错误,我们需要构造一个这种类型的值,这也是一个突破性的变化.

data …
Run Code Online (Sandbox Code Playgroud)

haskell servant

17
推荐指数
1
解决办法
372
查看次数

为什么我们需要总和类型?

想象一种语言,它不允许数据类型的多个值构造函数.而不是写作

data Color = White | Black | Blue
Run Code Online (Sandbox Code Playgroud)

我们会有

data White = White
data Black = Black
data Blue = Black
type Color = White :|: Black :|: Blue
Run Code Online (Sandbox Code Playgroud)

where :|:(这里不是|为了避免与sum类型混淆)是一个内置的类型union运算符.模式匹配可以以相同的方式工作

show :: Color -> String
show White = "white"
show Black = "black"
show Blue = "blue"
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,与副产品相比,它会产生扁平结构,因此您无需处理注射.而且,与sum类型不同,它允许随机组合类型,从而产生更大的灵活性和粒度:

type ColorsStartingWithB = Black :|: Blue
Run Code Online (Sandbox Code Playgroud)

我相信构造递归数据类型也不是问题

data Nil = Nil
data Cons a = Cons a (List a)
type List a = Cons a :|: Nil …
Run Code Online (Sandbox Code Playgroud)

haskell type-theory

11
推荐指数
3
解决办法
1096
查看次数

&^运算符有什么作用?

根据规范,这个运算符被称为bit clear:

&^   bit clear (AND NOT)    integers
Run Code Online (Sandbox Code Playgroud)

我以前从未听说过这样的操作员,我想知道它为什么有用.

它似乎采用左操作数并禁用右操作数中打开的所有位.是否有关于运营商的正式描述?我注意到的另一件事是它不是可交换的.Pococode与comarison ^:

11110 &^ 100 //11010
11110  ^ 100 //11010

11110 &^ 0 //11110
11110  ^ 0 //11110

11110 &^ 11110 //0
11110  ^ 11110 //0

11110 &^ 111 //11000
11110  ^ 111 //11001

111 &^ 11110 //1
111  ^ 11110 //11001
Run Code Online (Sandbox Code Playgroud)

bit-manipulation go

5
推荐指数
1
解决办法
150
查看次数

标签 统计

haskell ×2

bit-manipulation ×1

go ×1

ruby ×1

rubygems ×1

rvm ×1

servant ×1

type-theory ×1