gpt4 book ai didi

haskell - 为 MultiParamTypeClasses 注释不明确的类型变量

转载 作者:行者123 更新时间:2023-12-04 01:13:42 29 4
gpt4 key购买 nike

我正在使用一个类型类,我可以在其中“测量”类型 v 的某些属性。在 a 类型的对象上.例如,请考虑以下定义:

{-# LANGUAGE MultiParamTypeClasses #-}

data SizedElem a =
SizedElem
{ getSize :: Size
, getElem :: Elem a
}

newtype Size =
Size Integer

newtype Elem a =
Elem a

class Measured a v where
measureTypeClass :: a -> v

instance Measured (Elem a) (SizedElem a) where
measureTypeClass (Elem a) = SizedElem (Size 1) (Elem a)
尝试结合测量元素的功能,然后像这样提取尺寸
broken :: Elem a -> Size
broken = getSize . measureTypeClass
导致 GHC 的投诉:
Ambiguous type variable ‘a0’ arising from a use of ‘measureTypeClass’
prevents the constraint ‘(Measured
(Elem a) (SizedElem a0))’ from being solved.
...
Probable fix: use a type annotation to specify what ‘a0’ should be.
These potential instance exist:
instance Measured (Elem a) (SizedElem a)
天真地,我只是尝试在中间注释我期望的类型:
broken' :: Elem a -> Size
broken' xs =
let meas = measureTypeClass xs :: SizedElem a
in getSize meas
但是,这会导致稍微不同的错误:
No instance for (Measured (Elem a) (SizedElem a2))
arising from a use of ‘measureTypeClass’
In the expression: measureTypeClass xs :: SizedElem a
In an equation for ‘meas’:
meas = measureTypeClass xs :: SizedElem a
如果我理解正确,这意味着 a从注释解释 :: SizedElem a与类型签名中的类型不同。我如何告诉编译器这些应该是相同的类型变量?只需申请 {-# LANGUAGE ScopedTypeVariables #-}没有解决问题。
顺便说一句,对于特定类型,一切正常,例如
specificWorks :: Elem Char -> Size
specificWorks xs =
let meas = measureTypeClass xs :: SizedElem Char
in getSize meas
或者如果类型签名对于输入和输出具有相同的类型变量
elemWorks :: Elem a -> Elem a
elemWorks = getElem . measureTypeClass
此外,完全放弃类型类也有效,但对于我的实际应用程序,由于其他原因我需要类型类:
measureDirect :: Elem a -> SizedElem a
measureDirect (Elem a) = SizedElem (Size 1) (Elem a)

directWorks :: Elem a -> Size
directWorks = getSize . measureDirect

最佳答案

使用扩展 ScopedTypeVariables , 添加 forall函数签名的量词:

getSize' :: forall a. Elem a -> Size
getSize' xs =
let meas = measureTypeClass xs :: SizedElem a
in getSize meas
另一种适用于此的技术是 "constraint trick" .经验法则是永远不要有一个变量出现两次的实例头(在 => 的右侧),而是使用等式约束。
instance (a ~ b) => Measured (Elem a) (SizedElem b) where
measureTypeClass (Elem a) = SizedElem (Size 1) (Elem a)

关于haskell - 为 MultiParamTypeClasses 注释不明确的类型变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64046748/

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