Key*_*nan 9 haskell type-inference
在执行类型推断时,Haskell似乎无法解析'g == [a]'.任何想法如何使这项工作?
谢谢
module X where
import Control.Monad.State.Lazy
class Generator g where
next :: State g a
instance Generator ([] a) where
next = nextL
nextL :: State [a] a
nextL = state $ split
split :: [a] -> (a, [a])
split l = (head l, tail l)
Run Code Online (Sandbox Code Playgroud)
pig*_*ker 15
里德在他的评论中是正确的.当你写作
class Generator g where
next :: State g a
Run Code Online (Sandbox Code Playgroud)
你真的在说
class Generator g where
next :: forall a. State g a
Run Code Online (Sandbox Code Playgroud)
因此,从给定的状态开始g,您的客户可以生成a他们希望的任何类型的元素,而不是国家提供的任何类型g.
有三种明智的方法可以解决这个问题.我会按照我喜欢的顺序画出它们.
计划A是要认识到事物的任何生成器在某种意义上都是它们的容器,因此可以作为类型构造函数而不是类型呈现.它当然应该是a Functor并且具有高概率a Comonad.所以
class Comonad f => Generator f where
move :: forall x. f x -> f x
next :: forall x. State (f x) x
next = state $ \ g -> (extract g, move g)
-- laws
-- move . duplicate = duplicate . move
instance Generator [] where
move = tail
Run Code Online (Sandbox Code Playgroud)
如果这对您来说都是希腊语,也许现在是您在需要知道的基础上学习一些新结构的机会!
计划B是忽略comonadic结构并添加相关类型.
class Generator g where
type From g
next :: State g (From g)
instance Generator [a] where
type From [a] = a
next = state $ \ (a : as) -> (a, as)
Run Code Online (Sandbox Code Playgroud)
Plan C是"功能依赖"版本,与Cirdec建议的MonadSupply相似.
class Generator g a | g -> a where
next :: State g a
instance Generator [a] a where
next = state $ \ (a : as) -> (a, as)
Run Code Online (Sandbox Code Playgroud)
所有这些计划的共同点是,g和之间的功能关系在a某种程度上得到承认.没有它,没有什么可做的.
| 归档时间: |
|
| 查看次数: |
267 次 |
| 最近记录: |