类型类中的Haskell类型解析

类型类中的Haskell类型解析,haskell,type-inference,Haskell,Type Inference,Haskell在执行类型推断时似乎无法解析“g==[a]”。有没有办法让这一切顺利进行 Thx 里德的评论是对的。当你写作时 class Generator g where next :: State g a 你真的是说 class Generator g where next :: forall a. State g a 因此,从g中的给定状态,您的客户端可以生成他们想要的任何类型的a元素,而不是g中的状态提供的任何类型的元素 有三种合理的方法来解决这个问题。我会按照我喜欢的顺序画

Haskell在执行类型推断时似乎无法解析“g==[a]”。有没有办法让这一切顺利进行

Thx


里德的评论是对的。当你写作时

class Generator g where
  next :: State g a
你真的是说

class Generator g where
  next :: forall a. State g a
因此,从
g
中的给定状态,您的客户端可以生成他们想要的任何类型的
a
元素,而不是
g
中的状态提供的任何类型的元素

有三种合理的方法来解决这个问题。我会按照我喜欢的顺序画出来

计划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
如果这对你来说都是希腊语,也许现在是你在“需要知道”的基础上学习一些新结构的机会

计划B是忽略comonadic结构并添加一个关联的类型

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)

所有这些计划的共同点是,
g
a
之间的功能关系在某种程度上得到了承认。没有这一点,就什么也做不了。

你的类中的
a
与你实例中的
a
没有关系,因此你需要给
next
一个类型为
State[a]b
的值,或者更可能以某种方式修复您的类声明。看起来您正在尝试重新创建可能是
Generator NonEmpty
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)
class Generator g a | g -> a where
  next :: State g a

instance Generator [a] a where
  next = state $ \ (a : as) -> (a, as)