- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下运行良好的简化程序:
{-# LANGUAGE Rank2Types #-}
module Temp where
import Control.Monad.ST
import Control.Monad
import Data.STRef
mystery :: Int -> Int
mystery start =
let
run :: ST s Int
run = do
count <- newSTRef (1::Int)
loop count start
readSTRef count
in
runST run
loop :: STRef s Int -> Int -> ST s ()
loop cnt n = when (n /= 1)
(modifySTRef cnt succ >>
if n `mod` 2 == 0
then loop cnt (n `div` 2)
else loop cnt (n * 3 + 1))
我将 loop
定义移动到 do
block 中,以便能够像这样使用在 run
中创建的计数器:
mystery :: Int -> Int
mystery start =
let
run :: ST s Int
run = do
count <- newSTRef (1::Int)
let
loop :: Int -> ST s ()
loop n = when (n /= 1)
(modifySTRef count succ >>
if n `mod` 2 == 0
then loop (n `div` 2)
else loop (n * 3 + 1))
loop start
readSTRef count
in
runST run
这给了我以下错误:
Couldn't match type ‘s1’ with ‘s’
‘s1’ is a rigid type variable bound by
the type signature for:
loop :: forall s1. Int -> ST s1 ()
at ...
‘s’ is a rigid type variable bound by
the type signature for:
run :: forall s. ST s Int
at ...
Expected type: ST s1 ()
Actual type: ST s ()
In the expression:
...
我知道 s
不允许转义,但据我所知,它不会转义?此外,当我删除 loop
的类型签名时,问题就消失了。我想这表明他们的签名不知何故不正确,但它和以前一样,只是没有计数器,我不知道它应该是什么。
重命名 s
以匹配或不匹配 run
中提到的 s
没有区别。
最佳答案
首先,让我们重命名类型变量,以便它们更容易讨论,并删除与此错误无关的程序部分:
mystery :: Int
mystery = runST run
where run :: ST s Int
run = do
ref <- newSTRef 1
let read :: ST t Int
read = readSTRef ref
read
这表现出相同的行为,并注释掉 read
的类型签名像以前一样修复它。
现在,让我们问:ref
的类型是什么? ? newSTRef
的类型是 a -> ST s (STRef s a)
, 所以 ref :: STRef s Int
, 其中s
与 s
相同在 run
.
readSTRef ref
的类型是什么? ?嗯, readSTRef :: STRef s a -> ST s a
.所以,readSTRef ref :: ST s Int
, 其中 s 又是 run
定义中的那个
。你给它一个类型签名,声称它适用于任何 t
, 但它只适用于特定的 s
在 run
,因为它使用了该交易的引用。
不可能为我的read
写类型或者你的 loop
无需打开语言扩展即可让您引用 s
已经在范围内的类型变量。与 ScopedTypeVariables
,你可以这样写:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.ST
import Data.STRef
mystery :: Int
mystery = runST run
where run :: forall s. ST s Int
run = do
ref <- newSTRef 1
let read :: ST s Int
read = readSTRef ref
read
使用 forall
带来s
明确地进入范围,以便您可以引用它。现在内部类型签名的 s
实际上指的是外部变量,而不是一个新的阴影类型变量。这就是你如何向类型系统保证你只会使用这个 read
从拥有它使用的 ref 的事务内部运行。
您的原始程序,具有顶级 loop
, 出于类似的原因工作。而不是捕获 STRef
(因此它的 s
是隐含的),它声明了一个使用相同 s
的类型对于 ref 和交易。它适用于任何事务,只要它从该事务中获得引用即可。
关于haskell - 为什么我不能为本地 let bound ST 操作提供显式类型签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70324341/
在许多在线资源中,可以找到“内存”、“带宽”、“延迟”绑定(bind)内核的不同用法。在我看来,作者有时会使用他们自己对这些术语的定义,我认为这对某人做出明确区分非常有益。 据我了解:带宽绑定(bin
FIFO、LIFO 和LC Branch and Bound 有什么区别? 最佳答案 Branch & Bound 通过使用估计边界来限制可能解决方案的数量来发现完整搜索空间内的分支。不同的类型(FI
我有一个网页,其中有一些 Kendo 控件(例如下拉菜单和按钮)可以正常工作,但是添加Grid 会导致问题。 @(Html.Kendo().Grid(Model).Name("grid").Colu
术语“CPU 限制”和“I/O 限制”是什么意思? 最佳答案 这非常直观: 如果 CPU 更快,程序就会运行得更快,即程序的大部分时间只是使用 CPU(进行计算),则该程序是 CPU 密集型。 计算
我在以下代码段中遇到问题并发出警告,希望您能帮助我: fprintf (fp, "%dd%d+%d ", pMobIndex->mana[DICE_NUMBER], DICE_NUMBER 在我
swift 2 let gap = CGFloat(randomInRange(StackGapMinWidth...maxGap)) Missing argument label 'range:'
swift 2 let gap = CGFloat(randomInRange(StackGapMinWidth...maxGap)) Missing argument label 'range:'
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 关闭 6 年前。 这个问题是由于打字错误或无法再重现的问题引起的。虽然类似的问题可能是on-topic在
我想在gcc8.2下启用数组边界检查,这样可以帮助在编译期间检查数组下标是否越界,它可能会给出如下警告:数组下标高于数组边界 [-Warray-bounds] 我使用 coliru 做了一个演示: #
我只是想知道在 Apple API 中的什么地方定义了变量“bounds.minX”、“bounds.maxX”?我查看了“UIView”和“CGRect”文档,但似乎找不到它? 最佳答案 它包含在"
我想覆盖整个屏幕。我想将其框架设置为覆盖整个屏幕。浏览堆栈溢出时,我发现了这两种不同的设置 View 框架以覆盖屏幕的方法: [UIScreen mainScreen].bounds [UIApplc
在协程中执行 IO 绑定(bind)函数(例如,从后端请求数据)给了我一个优势,即在请求结果可用之前暂停它的执行,对吗?但是,受 CPU 限制的函数(例如,解析一个巨大的文本文件)不会“等待”任何东西
public class ChampionsLeague> extends League{ ... 如何创建此类的实例? ChampionsLeague league = new ChampionsL
我遇到了以下问题: 我有这些类和接口(interface)定义 public abstract class ViewModelRefreshPostListFragment> extends
我注意到在使用 (Swift 4.0) 的 IOS X 代码中,我至少可以通过以下两种方式请求 View 的高度 V: V.bounds.size.height 和... V.bounds.heigh
swift 中 bounds.size.width 和 bounds.width 有什么区别?他们会返回同样的东西吗?谢谢! 最佳答案 bounds 是 UIView 的 CGRect 结构属性,其中
在我看来不可能包含 Integer.MAX_VALUE和Long.MAX_VALUE创建 IntStream 时尽可能使用随机值或LongStream使用 java.util.Random 的边界类。
我有二叉树类: public class BinaryTree> extends AbstractTree { protected TreeNode root;
我最近做了并更新了我的 Xamarin iOS 项目,我曾经能够调用以下代码来检索屏幕宽度和高度: if (orientation == UIInterfaceOrientation.Landscap
我仍然不明白为什么我收到这个警告 array subscript is above array bounds [-Warray-bounds] 对于一个小的 C 代码如下: #include #in
我是一名优秀的程序员,十分优秀!