gpt4 book ai didi

haskell - RankNTypes中forall的用途

转载 作者:行者123 更新时间:2023-12-04 13:49:26 25 4
gpt4 key购买 nike

hlint 的帮助下编写一些 Haskell 代码,我按照提示为函数添加类型签名。它注入(inject)了类似这样的东西:

{-# LANGUAGE RankNTypes #-}

multipleOf :: forall a. Integral a => a -> a -> Bool
multipleOf divisor n = n `mod` divisor == 0

这种语言扩展对我来说是新的,但据我所知,这与更简单的相同:
multipleOf :: Integral a => a -> a -> Bool
multipleOf divisor n = n `mod` divisor == 0

我读过的每个等级 N 类型的例子似乎都没有在已经可用的多态性上添加任何新的东西,而这个 forall语法似乎没有增加任何值(value)。

我错过了什么?有没有一个很好的例子说明 forall语法是否超出了没有扩展的可用范围?

最佳答案

您缺少可以限制量化类型变量的范围:

modifyPair :: (Num b, Num c) => (forall a. Num a => a -> a) -> (b, c) -> (b, c)
modifyPair f (b, c) = (f b, f c)

尝试在没有 RankNTypes 的情况下编写该函数扩大。特别是,允许​​该对的元素是彼此不同的类型。

这个具体的例子不是很有用,但一般的想法是成立的。您可以指定函数的参数必须是多态的。

您可以使用此工具执行一个额外的技巧。典型例子来自 ST . ST 的目标库是为了允许限制使用可变数据。也就是说,您可以实现一个涉及真正变异的算法,并提供一个纯粹的外部接口(interface)。 ST它本身负责通过巧妙的类型系统技巧证明使用是安全的:
newtype ST s a    = ... -- details aren't important
newtype STRef s a = ... -- details still aren't important

-- a standard-ish interface to mutable data
newSTRef :: ST s (STRef s a)
readSTRef :: STRef s a -> ST s a
writeSTRef :: STRef s a -> a -> ST s ()

-- the magic using RankNTypes
runST :: (forall s. ST s a) -> a

那个额外的类型变量, s ,值得关注。它同时出现在 STSTRef .每个操作 STRef 的函数确保 sSTSTRef是同一个类型的变量。所以当你到达 runST ,你会发现类型 s必须与类型 a 无关. s其范围比 a 的范围更有限.这样做的最终结果是你不能写像 runST newSTRef 这样的东西。 .类型检查器将拒绝它,因为类型变量 s将不得不逃避它被量化的上下文。

因此,当您可以指定函数的参数必须是多态的时,您确实可以使用一些方便的技巧。

关于haskell - RankNTypes中forall的用途,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29417839/

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