【问题标题】:Non type-variable argument for MonadWriterMonadWriter 的非类型变量参数
【发布时间】:2017-12-14 15:40:08
【问题描述】:

我只是尝试使用writer

writer (5, "Hello, World")

但我注意到我收到了一个错误:

约束MonadWriter [Char] m中的非类型变量参数

但我想知道我没有满足什么约束? [a] 毕竟是 Monoid...

【问题讨论】:

  • 该特定错误消息的另一部分应该告诉您如何修复它。您可以使用{-# LANGUAGE ... #-} pragma 启用它的建议。
  • 它告诉我允许 FlexibleContexts。但为什么这甚至是必要的?我满足所有限制条件?
  • 这里其实没有问题。你确实满足了所有的约束。 GHCi 不会打印任何结果的原因是它不知道整个事情应该是什么确切类型——你没有指定。实际上,通常没有必要,因为类型将从上下文中推断出来,但前提是存在 某些上下文(例如,将整个事物包装在 runWriter 中)。
  • 是的,强制类型 writer (5,"foo") :: Writer String Char 有效。但为什么会有这种行为? Control.Monad. 中的所有其他 monad 都没有这种行为...
  • 如果没有FlexibleContextsMonadWriter [Char] m 根本就不是有效类型(但它是给定表达式的推断类型的约束,因此给定表达式的类型不正确)。其他 monad 转换器也会发生同样的事情(例如 put "x"('a':) <$> ask

标签: haskell monads


【解决方案1】:

这只是保持类型检查“简单”的检查

writer (5, "Hello world") :: (MonadWriter String m, Num n) => m n

这是一个非常明智的类型。但是,默认情况下是不允许的,因为约束MonadWriter String m 包含一个类型参数String,它不是变量。这样做是为了阻止类型错误的延迟:

class C c where c :: c -> c
-- no instance C Int
x :: C Int => Int
x = c (5 :: Int)
-- illegal with above restriction
-- missing instance error (maybe) delayed to user without

只需设置-XFlexibleContexts 即可禁用检查。

至于其他 monad,我很确定 ReaderStateFree 也会这样做。

【讨论】:

    猜你喜欢
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多