gpt4 book ai didi

haskell - 为什么 GHC.Types.Any 在这里?

转载 作者:行者123 更新时间:2023-12-02 01:45:53 25 4
gpt4 key购买 nike

刚才我在 Haskell 中做一些代码高尔夫,我遇到了一个当时对我没有多大意义的错误。决定在 GHCi 中检查一下,现在我真的很困惑。

λ> :t replicate <$> readLn
replicate <$> readLn :: IO (a -> [a])
λ> f <- replicate <$> readLn
-- I type 4 and press Enter
λ> :t f
f :: GHC.Types.Any -> [GHC.Types.Any]

为什么是 f不属于 a -> [a] 类型?我可以 unsafeCoerce ,当然,但这是冗长而可怕的。

最佳答案

IO (a -> [a])是一种多态类型。展开,表示forall a. IO (a -> [a]) .现在,有两件事在这里行不通。一,这是一个多态的IO产生单态函数的 Action 。本质上,此操作的每次执行都会为一种类型生成一个函数。 a -> [a]不是真正有效的类型,但如果你的意思是你想要一个 forall a. a -> [a] ,你不会得到一个:

main = do
f <- replicate <$> readLn
print (f (5 :: Int)) -- f can be *one of* Int -> [Int] or Float -> [Float], but not both
print (f (5 :: Float)) -- doesn't compile, comment either line out and it will

第二,GHC 不支持隐含多态性。理论上,如果你写了 IO正确操作,您可以将其设置为 IO (forall a. a -> [a]) ,但 GHC 不支持将多态类型(如 forall a. a -> [a] )放入容器中,如 IO .

在你的情况下,因为你不使用 f , GHC 不知道应该在哪个类型上实例化action,但它必须选择一个,所以它默认为 Any .

编辑:绕过“无意义类型”限制的传统方法是将它们隐藏到 newtypes :
{-# LANGUAGE RankNTypes #-}
-- interestingly, this is a numeric type (it represents the natural numbers)
newtype Replicator = Replicator { runReplicator :: forall a. a -> [a] }
mkReplicator :: Int -> Replicator
mkReplicator i = Replicator (replicate i)
-- mkReplicator =# replicate
main = do
Replicator f <- mkReplicator <$> readLn
print (f (5 :: Int))
print (f (5 :: Float)) -- should work now

应该是不值得...

关于haskell - 为什么 GHC.Types.Any 在这里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61805899/

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