【问题标题】:Expressing typeclass relations with functional dependencies in Haskell在 Haskell 中用函数依赖表示类型类关系
【发布时间】:2013-01-25 09:41:48
【问题描述】:

我想表达我有 3 个相关的类型类。

我有两个文件。第一:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module ModA where

class Class a b c | a -> b, b -> c where
    getB :: a -> b
    getC :: b -> c

第二:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
module B where

import qualified ModA

data A = A {f1::String}

data B = B {f2::String}

data C = C {f3::String}

instance ModA.Class A B C where
    getB a = B "hey"
    getC a = C "ho"

getABForMe = ModA.getB (A "boo")

getACForMe = ModA.getC (B "yo")

我得到的错误:

No instance for (ModA.Class a0 B C)
  arising from a use of `ModA.getC'
Possible fix: add an instance declaration for (ModA.Class a0 B C)
In the expression: ModA.getC (B "yo")
In an equation for `getACForMe': getACForMe = ModA.getC (B "yo")

我错过了什么?

【问题讨论】:

    标签: haskell typeclass functional-dependencies


    【解决方案1】:

    你可以使函数依赖“循环”:

    class Class a b c | a->b, b->c, c->a where
        getB :: a -> b
        getC :: b -> c
    

    所以任何一个类型参数都可以从其他任何一个类型参数中推导出来。但我不确定你是否真的想要这个;为什么不只创建一个类型类,其中包含一个fundep 和一个方法,并创建两个实例(instance Class A Binstance Class B C)?

    【讨论】:

    • 就是这样!工作完美,谢谢。在为什么部分,我工作的真实代码比这个对称的小例子更复杂。这个循环fundep解决方案算作hackish吗?
    【解决方案2】:

    GHC 无法知道getC 的调用中第一类参数a 的类型。该调用将b 修复为B 类型,然后函数依赖允许GHC 推断c 必须是C。但是没有关于a 的信息。

    【讨论】:

    • 那我该如何解决呢?
    猜你喜欢
    • 2016-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 2018-12-10
    相关资源
    最近更新 更多