gpt4 book ai didi

haskell - 使用关联类型族时推断类型类约束

转载 作者:行者123 更新时间:2023-12-04 00:06:35 25 4
gpt4 key购买 nike

我知道 you can add constraints on associated type families and data families .这样做是对您类(class)的所有实例实现约束。

但我不知道如何在实例派生或函数声明中推断出这些约束。例如,这段代码无法进行类型检查:

{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}

import Data.Proxy ( Proxy )

class Eq (FooT a) => Foo a where
type FooT a :: *

-- Can't infer it in an instance derivation
data CantInferEq a = CantInferEq (FooT a) deriving Eq

-- Also can't infer it in a function declaration.
-- The Proxy is there to avoid non-injectivity issues.
cantInferEq :: Proxy a -> FooT a -> FooT a -> Bool
cantInferEq _ x y = x == y

错误信息是:

Test.hs:11:52: No instance for (Eq (FooT a)) …
arising from the first field of ‘CantInferEq’ (type ‘FooT a’)
Possible fix:
use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Eq (CantInferEq a))

Test.hs:16:23: No instance for (Eq (FooT a)) arising from a use of ‘==’ …
In the expression: x == y
In an equation for ‘cantInferEq’: cantInferEq _ x y = x == y

Compilation failed.

这是怎么回事?是否有解决方法来获得我想要的行为?

最佳答案

问题的症结在于,只给定一个 FooT a,您无处可以从中提取 Eq 实例字典。

解决方法是在您的类型类要求中明确说明,从而有一个地方可以传递 Eq 字典:

{-# LANGUAGE StandaloneDeriving, UndecidableInstances #-}

data CantInferEq a = CantInferEq (FooT a)
deriving instance (Eq (FooT a)) => Eq (CantInferEq a)

cantInferEq :: (Eq (FooT a)) => Proxy a -> FooT a -> FooT a -> Bool
cantInferEq _ x y = x == y

或者您可以通过使用 CantInferEq 构造函数打包 Eq (FooT a) 字典来避免使用 UndecidableInstances:

{-# LANGUAGE GADTs, StandaloneDeriving #-}
data CantInferEq a where
CantInferEq :: (Eq (FooT a)) => FooT a -> CantInferEq a
deriving instance Eq (CantInferEq a)

关于haskell - 使用关联类型族时推断类型类约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38045091/

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