class - 无法显示 haskell 中实例函数的结果

标签 class haskell show instances

class (Eq k, Ord k, Show k) => KEY k where
  keyBuild    :: NumId -> NumId -> NumId  -> k
  keyDummy    :: k
  keyFromList :: [NumId] -> k
  -- keyGenerate :: (DATAPOOL p) => p -> Int -> [k]  -- p = Pool k e s


newtype PrimaryKey = PK (NumId, NumId, NumId) deriving (Eq, Ord, Show) 

instance KEY PrimaryKey where
  keyBuild k0 k1 k2 = PK (k0,k1,k2)
  keyDummy          = PK (0,0,0)
  keyFromList is    = keyFromList (take 3 (is ++ (replicate 3 0)))
  keyGenerate p cnt = let
                        ks = keys p
                        pks = map (\l ->  keyFromList (randomize l))                   (replicate cnt 3)
                      in pks

在 ghci 中我愿意

let k1 = keyBuild 1 2 3
let k2 = PK (1,2,3)
k1 == k2 
True
k2
PK (1,2,3)

并按预期得到 True 和 k2 的值,但是

k1
231:1: error:
    • Ambiguous type variable ‘a0’ arising from a use of ‘it’
      prevents the constraint ‘(KEY a0)’ from being solved.
      Probable fix: use a type annotation to specify what ‘a0’ should be.
      These potential instance exist:
        instance [safe] KEY PrimaryKey -- Defined at Work

预期PK(1,2,3) PrimaryKey 有派生(Eq、Ord、Show),那么我做错或错过了什么?

最佳答案

您尚未为 k1 指定固定类型。由于 keyBuild 可以使用正确的实例构造任何类型的 key ,因此它具有多态类型 k1::KEY k => k。这很好,因为您可以将 k1 与不同具体类型的键进行比较......在您的情况下,您已经使用 k2::PrimaryKey 进行了尝试,但您可以也可以将 k1 == k3k3::SomeOtherKeyType 一起使用,前提是 SomeOtherKeyType 也是 KEY 的实例class – 在这种情况下,k1 也将简单地“接管”类型 SomeOtherKeyType

另一方面,k1 没有特定类型。事实上它可能是任何适用的类型,但是编译器如何知道你想要哪个类型呢?当使用 == 时,两侧必须是相同的类型,因此一侧有一个具体类型就足够了,但 k1 本身是不明确的。

碰巧在你的模块中只有一个匹配的实例,即KEY PrimaryKey,但通常会有很多(或零个!)这样的实例。如果编译器随意选择一个,那会很奇怪,不是吗?

所以如果你想显示k1,你需要手动选择一种类型。很容易做到,只需添加本地签名即可:

*Main> let k1 = keyBuild 1 2 3
*Main> :t k1
k1 :: KEY k => k
*Main> k1 :: PrimaryKey
PK (1,2,3)

关于class - 无法显示 haskell 中实例函数的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46090803/

相关文章:

c++ - 作为参数传递给 C++ 中的类时的内存丢失

haskell - 如何用 Haskell 向量编写并行代码?

json - 试图解析递归 JSON,我在正确的轨道上吗?

linux - XMonad:按下生成键时具有焦点的 SpawnOn 工作区

grails - Grails Controller 添加实例

swift - 在 Swift 中的同一个 VC 上点击按钮后,有没有办法显示以前隐藏在早期代码行中的 UIelement?

java - 在不同的方法中访问和使用自定义对象和 ArrayList<Object>

C++ 类头和实现错误

c++ - 不销毁作为 union 成员的类类型的对象是否安全?

javascript - 使用 HTML 和 Javascript 使用 4 个单选按钮显示和隐藏输入字段