haskell - 在 GHCI 中时正确的行为,在文件中时键入错误

标签 haskell types

给出定义:

 {-# LANGUAGE ExistentialQuantification, TypeFamilies, FlexibleInstances, FlexibleContexts, ScopedTypeVariables #-}
 class Monad m => RunableMonad m where
   type ReturnType m :: * -> *
   run :: m a -> ReturnType m a

当我输入 GHCI 时

:t \x -> [run $ return x]

它给了我正确的表达式类型:

\x -> [run $ return x] :: RunableMonad m => a -> [ReturnType m a]

但是当我将以下定义放入文件中时,它给出了类型错误:

single :: RunableMonad m => a -> [ReturnType m a]
single x = [run $ return x]

Could not deduce (ReturnType m0 ~ ReturnType m)
from the context (RunableMonad m)
  bound by the type signature for
             single :: RunableMonad m => a -> [ReturnType m a]
  at concurrency-simulator.hs:467:11-49
NB: ‘ReturnType’ is a type function, and may not be injective
The type variable ‘m0’ is ambiguous
Expected type: a -> [ReturnType m a]
  Actual type: a -> [ReturnType m0 a]
In the ambiguity check for:
  forall a (m :: * -> *). RunableMonad m => a -> [ReturnType m a]
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘single’:
  single :: RunableMonad m => a -> [ReturnType m a]

最佳答案

我认为在这种情况下 GHCi 的 :t 的结果本质上是错误的,并且您将永远无法实际使用表达式 run $ return x .

问题是你的类定义中没有限制说两个不同的 Monads m0m (使用与错误消息的名称相同)不能具有相同 ReturnType

这意味着,当查看使用 run $ return x 的上下文时,GHC 可能能够推断出结果 ReturnType m a 是什么,并从x 的类型可以推断出 a 是什么,但无法从中推断出实际的 monad m 是什么。

但是,您应该能够明确地告诉它:run (return x::WhateverTypeYouReallyWant)

仅当您在像 return x 这样的表达式上使用 run 时才需要添加显式类型注释,该表达式具有多态性,可以属于多个 monad。 (或者任何单子(monad),在这种情况下。)

关于haskell - 在 GHCI 中时正确的行为,在文件中时键入错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24376338/

相关文章:

javascript - Interpreter - 闭包是如何得名的?

haskell - 缩进错误代码的工具

java - 整数到尺寸较小的字符的内部转换

Haskell - 采用相同映射的函数映射

typescript - string[] 和 [string] 的区别

haskell - 在变压器堆栈的底部插入 ErrorT

haskell - haskell中有没有一种方法可以通过多个参数和不同的顺序进行紧凑有效的比较

ios - 将 Haskell 翻译成 C 以便在 iPhone 上使用

c# - 类和数据类型有什么区别?

c++ - 添加具有 size_t 类型值的指针