- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
玩弄教堂的数字。我遇到了无法指导 GHC 类型检查器处理高阶类型的情况。
首先我编写了一个版本,没有任何类型签名:
module ChurchStripped where
zero z _ = z
inc n z s = s (n z s)
natInteger n = n 0 (1+)
add a b = a b inc
{-
*ChurchStripped> natInteger $ add (inc $ inc zero) (inc $ inc $ inc zero)
5
-}
mult a b = a zero (add b)
{-
*ChurchStripped> natInteger $ mult (inc $ inc zero) (inc $ inc $ inc zero)
6
-}
mult
的推断类型非常糟糕,因此我尝试使用类型定义来清理类型:
module Church where
type Nat a = a -> (a -> a) -> a
zero :: Nat a
zero z _ = z
inc :: Nat a -> Nat a
inc n z s = s (n z s)
natInteger :: Nat Integer -> Integer
natInteger n = n 0 (1+)
{- `add :: Nat a -> Nat a -> Nat a` doesn't work, and working signature looks already suspicious -}
add :: Nat (Nat a) -> Nat a -> Nat a
add a b = a b inc
{-
*Church> natInteger $ add (inc $ inc zero) (inc $ inc $ inc zero)
5
-}
mult :: Nat (Nat a) -> Nat (Nat a) -> Nat a
mult a b = a zero (add b)
{-
*Church> natInteger $ mult (inc $ inc zero) (inc $ inc $ inc zero)
6
-}
它可以工作,但类型并不像应有的那么干净。继System F我尝试过的定义:
{-# LANGUAGE RankNTypes #-}
module SystemF where
type Nat = forall a. a -> (a -> a) -> a
zero :: Nat
zero z _ = z
inc :: Nat -> Nat
inc n z s = s (n z s)
natInteger :: Nat -> Integer
natInteger n = n 0 (1+)
{- This doesn't work anymore
add :: Nat -> Nat -> Nat
add a b = a b inc
Couldn't match type `forall a1. a1 -> (a1 -> a1) -> a1'
with `a -> (a -> a) -> a'
Expected type: (a -> (a -> a) -> a) -> a -> (a -> a) -> a
Actual type: Nat -> a -> (a -> a) -> a
In the second argument of `a', namely `inc'
In the expression: a b inc
In an equation for `add': add a b = a b inc
-}
我想应该可以用 Nat -> Nat -> Nat
类型签名编写 add
,但我不知道如何实现。
附注实际上我是从底层开始的,但这样表达这个问题可能更容易。
最佳答案
bennofs 是对的,你真的想在这里帮助类型检查器,特别是在 add
中。您需要在其中实例化 a
在forall a . a -> (a -> a) -> a
与 Nat
(即相同的 forall a . ...
类型)。
一种方法是引入一个包装多态类型的新类型:
newtype Nat' = N Nat
现在您可以在 Nat
之间切换和Nat'
通过N
,然后使用 unN
返回
unN :: Nat' -> Nat
unN (N n) = n
(此时值得注意的是 newtype Nat' = N Nat
与 data Nat2 = forall a . N2 (a -> (a -> a) -> a)
是不同的野兽。后者需要 -XExistentialQuantification
因为它表示对于 a
的某些特定选择,您可以创建 Nat2
。另一方面,前者仍然说,如果你有 a -> (a -> a) -> a
对于任何任意 a
,那么你可以制作一个 Nat'
。对于 Nat'
你需要 -XRankNTypes
,但你不需要存在。 )
现在我们还可以制作inc'
增加 Nat'
:
inc' :: Nat' -> Nat'
inc' (N n) = N (inc n)
我们准备添加:
add :: Nat -> Nat -> Nat
add n m = unN (n (N m) inc')
这样做的原因是因为现在不再试图说服 GHC 实例化 n
的类型具有多态类型 ∀ a . a -> (a -> a) -> a
就其本身而言,N
充当提示。
示例:
> natInteger (add (inc zero) (inc zero))
2
关于haskell - 如何与更高级别的类型合作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21259931/
有什么创意可以在不执行 O/S Thread.Sleep(10) 的情况下通过合作/非抢占式多任务处理来避免 yield 或 sleep 上的死锁?通常 yield 或 sleep 调用将回调到调度程
我在 httpd.conf 中取消注释了以下行: LoadModule php5_module libexec/apache2/libphp5.so 当我转到任何 php 页面时,文件会下载而不是显示
我正在创建一个新的支付应用程序。我有一个客户端应用程序,用户可以选择价格,输入其身份验证信息,然后客户端创建 iso 8583 消息并将此数据发送到银行服务器。 根据我的研究,我可以使用 jPOS 来
我正在尝试这个简单的代码: import java.util.List; import com.orientechnologies.orient.core.exception.OStorageExce
当我去列表时,这将像这样弹出子列表。这是使用 Chrome 和 Opera。但是在火狐浏览器中是这样显示的。 HTML代码 Categories Printing Mate
尝试使用 bc 对数组中的元素求和,我有一个包含名称和其值的文件,如果名称出现 3 次,我应该将其值乘以 3,然后找到所有元素的总和,我看到标准输入错误 $ cat foo.txt max 2.3 h
一般来说,是否有一个接口(interface)表明TransactionScope-awareness?是否有利用 TransactionScope 的常用数据库列表? (它是扩展 DbConnect
我想知道为什么没有确定的方法来处理 Jackson。我只想解析 JSON 字符串: ObjectMapper mapper = new ObjectMapper(); Customer[] myObj
Expo是很棒的。它的目标之一是仅使用 javascript 来编写 React Native 应用程序。 您如何确定第三方 React Native 库是否可以在 Expo 开发环境中工作? 最佳答
我有一个 Rad 组合框和 2 个 RadGrid - grvUser 和 grvRole grvUser RadGrid如下...
我一直在努力 Unsafe JavaScript attempt to access frame with URL http://lolfantasy.net/ from frame with URL
我有这种电子邮件表 id | url | id1 | id2 | mail_date | message 我的行示例 id | url | id1 | id2 | mail_date | messag
我正在尝试弄清楚如何使用委托(delegate)和协议(protocol)。 我有一个 MessageFetcher 类,它从 url 中获取消息。 class MessageFetcher { f
所以我已经尝试了几个星期让 GLFW3 与 MinGW 一起工作(通过 Code::Blocks IDE),但每次都失败了。我在每个 glfw 参数中都得到了一大堆“ undefined refere
当我写这段代码时,我在 Scala 中遇到编译错误 var s: Stack[_ ,这显然是一个错误。 这解释了为什么做 x :: xs不危险。现在来解释为什么它会打字: :: 的签名在 List[
我刚开始一个非常简单的项目,并尝试同时使用 ButterKnife 和 Jack 编译器,但它们似乎不能很好地相互配合。 Gradle插件版本:2.2.0-alpha5 在我的模块 build.gra
我一直在关注本指南(并通过 Composer 安装了所有内容):http://docs.behat.org/cookbook/behat_and_mink.html并试图让 Behat + Mink
我无法让 Google 的 Repo、gerrit 和 Jenkins 一起工作。 我们的设置: 我们有一个由几个 git 存储库构建的 Repo,它们都在我们的 gerrit 服务器上。 list
我使用 iText 库来创建并操作 PDF 文档。让我们有一个包含简单字符串的文档,例如“Hello world”。所以在pdf文件结构中,我们必须有(Hello world)Tj。问题是我如何通过使
我在 Jasper 中为 noto-sans 字体 ( https://www.google.com/get/noto/#sans-lgc ) 创建了一个字体扩展,并将其添加到我的类路径中。我的应用程
我是一名优秀的程序员,十分优秀!