gpt4 book ai didi

haskell - 在Haskell中,如何使用继承的参数显式地为这个特定的子函数提供签名?

转载 作者:行者123 更新时间:2023-12-02 02:49:44 27 4
gpt4 key购买 nike

假设你有这个功能

import Control.Monad
import Control.Monad.ST
import Data.STRef

f :: (Num a, Ord a) => STRef s a -> ST s ()
f i = loop
where
loop = do
_i <- readSTRef i
writeSTRef i (_i - 1)
when (_i > 1) loop

loop的 body ,i被隐式定义,因为它是 f 中的参数。但是我在给loop签名时遇到了麻烦。 。 Hie 告诉我它应该是 ST s () ,所以我写 loop :: ST s ()就在 loop 上方的定义。

但是 ghc 提示它无法匹配 s来自loops来自f 。如loop没有参数,它创建自己的本地 forall s.在该循环的定义中,它阻止与 f 匹配的s

但令人惊讶的是它在没有显式签名的情况下进行编译。 PartialTypeSignature 可以工作,但它很丑陋,并且不允许引用 s 。如果我只添加 i 它也会编译作为 loop 的参数但假设我很懒。

如何明确指定loop的签名以可编译的方式?

所有使用隐式类型编译的东西都可以被赋予显式类型,以便它仍然可以编译,这不是真的吗?

最佳答案

解决方案确实在于-XScopedTypeVariables

问题来自这样一个事实:如果您想引用一个已经存在的类型变量,则必须显式量化该变量。

{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad
import Control.Monad.ST
import Data.STRef

f :: forall s a. (Num a, Ord a) => STRef s a -> ST s ()
f i = loop
where
loop :: ST s ()
loop = do
_i <- readSTRef i
writeSTRef i (_i - 1)
when (_i > 1) loop

关于haskell - 在Haskell中,如何使用继承的参数显式地为这个特定的子函数提供签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62211204/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com