gpt4 book ai didi

haskell - 无法从上下文错误中推断出包含的约束

转载 作者:行者123 更新时间:2023-12-03 09:39:31 25 4
gpt4 key购买 nike

我正在努力在 Haskell 中重新创建一些基本的类别理论,但遇到了一个问题。我的代码看起来像这样 - 非常标准。当然,这是隐藏 id 和 (.)。

class Category c where
id :: forall a. c a a
(.) :: c b d -> c a b -> c a d

-- Recover usual behavior of . and id
instance Category (->) where
id = \x -> x
(.) = \f g x -> f $ g x

class (Category c, Category d) => Functor c d f where
fmap :: c a b -> d (f a) (f b)

data Comp f g x = Comp {getComp :: f (g x)}

instance (Category c, Category d, Category e,
Functor d e f, Functor c d g) => Functor c e (Comp f g) where
fmap = _

最后一个实例声明抛出了一个非常丑陋的错误,
• Could not deduce (Functor d0 e f)
from the context: (Category c, Category d, Category e,
Functor d e f, Functor c d g)
bound by an instance declaration: ...
type variable d0 is ambiguous.

我已经玩了一段时间了,我不太明白发生了什么。我对haskell很陌生。

最佳答案

让我们尝试修复您的代码

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE UndecidableInstances #-}
import Prelude hiding (Functor, fmap, id, (.))
import Data.Coerce

class Category c where
id :: forall a. c a a
(.) :: c b d -> c a b -> c a d

coerceC :: Coercible a b => c a b

-- Recover usual behavior of . and id
instance Category (->) where
id = \x -> x
(.) = \f g x -> f $ g x

coerceC = coerce

class (Category c, Category d) => Functor c d f where
fmap :: c a b -> d (f a) (f b)

到现在为止还挺好。我加了 coerceC方法 Category ,我们很快就会看到原因。
( profunctors 包定义了 .##. 用于大致相同的目的: http://hackage.haskell.org/package/profunctors-5.2.2/docs/Data-Profunctor-Unsafe.html#t:Profunctor )

接下来我们需要写一些具体的东西来获得洞察力。让我们试试 []仿函数:
instance Functor (->) (->) [] where
fmap = map

请注意 []是仿函数 (->) -> (->) .洞察力是那个仿函数
确定/“知道”源和目标类别。我们可以告诉 GHC
通过 FunctionalDependencies .
class (Category c, Category d) => Functor c d f | f -> c d where
fmap :: c a b -> d (f a) (f b)

然后我们可以继续 Comp例子。笔记:
- 这是一个 newtypecoerceC上类
- 我掉线了 Category约束,正如 Functor 所暗示的那样
newtype Comp f g x = Comp {getComp :: f (g x)}

instance (Functor d e f, Functor c d g) => Functor c e (Comp f g) where
fmap = _

现在我们得到一个类型洞错误,我们期待:
Found hole: _ :: c a b -> e (Comp f g a) (Comp f g b)

这是我们可以填写的
instance (Functor d e f, Functor c d g) => Functor c e (Comp f g) where
fmap :: forall a b. c a b -> e (Comp f g a) (Comp f g b)
fmap ab
= coerceC
. (fmap (fmap ab :: d (g a) (g b)) :: e (f (g a)) (f (g b)))
. coerceC

(编写类型中间签名有助于把事情做好,在这种情况下我们至少需要一个,因为 coerceC 是非常多态的)

关于haskell - 无法从上下文错误中推断出包含的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50611254/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com