说我有以下内容:
import Control.Monad.Random
foo :: IO Float
foo = fmap realToFrac getRandom
Run Code Online (Sandbox Code Playgroud)
GHC正确地抱怨不知道其类型getRandom; 我可以解决这个问题
foo = fmap realToFrac (getRandom :: IO Double)
Run Code Online (Sandbox Code Playgroud)
但是,请考虑我所拥有的情况:
foo :: (Functor m, MonadRandom m) => m Float
foo = fmap realToFrac getRandom
Run Code Online (Sandbox Code Playgroud)
我做不到
foo = fmap realToFrac (getRandom :: m Double)
Run Code Online (Sandbox Code Playgroud)
我必须重复这个MonadRandom约束:
foo = fmap realToFrac (getRandom :: MonadRandom m => m Double)
Run Code Online (Sandbox Code Playgroud)
由于存在大量约束,这将导致大量额外输入.我宁愿不必那样做.我知道我可以使用ScopedTypeVariables:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Random
foo :: MonadRandom m => m Float
foo = do
x :: Double <- getRandom
return (realToFrac x)
Run Code Online (Sandbox Code Playgroud)
但这也很冗长,而且我不能在所有这些情况下应用它.
我也知道这个PartialTypeSignatures提议.我想这可能让我这样做:
foo = fmap realToFrac (getRandom :: _ Double)
Run Code Online (Sandbox Code Playgroud)
但是我对其(长)描述的扫描并不完全清楚.不幸的是,PartialTypeSignatures尚未准备好迎接黄金时段,因此尚未包含在GHC的发布版本中.
我显然欢迎其他的建议,而是一个解决这个问题,我能想到的是一些方法来识别m与n在以下几点:
foo :: (Functor m, MonadRandom m) => m Float
foo = fmap realToFrac (getRandom :: n Double)
Run Code Online (Sandbox Code Playgroud)
这种事可能吗?
你的直觉是正确的:ScopedTypeVariables是这项工作的正确延伸:
{-# LANGUAGE ScopedTypeVariables #-}
import Control.Monad.Random
foo :: (Functor m, MonadRandom m) => m Float
foo = fmap realToFrac (getRandom :: m Double)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |