gpt4 book ai didi

haskell - 什么是多态/多类型元组?

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

当我正在浏览 haskell-excercises问题。我看到下面的代码创建了一个聚合 Constraint通过将每种类型应用于约束构造函数。在 GHC 中,Constraint 的元组似乎嵌套得很深。 s 仍然亲切 Constraint (也许变平了?)。

{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}


type family All (c :: Type -> Constraint) (xs :: [Type]) :: Constraint where
All c '[] = ()
All c (x ': xs) = (c x, All c xs)

-- >>> :kind! All
-- All :: (* -> Constraint) -> [*] -> Constraint
-- = All

-- >>> :kind! All Eq '[Int, Double, Float]
-- All Eq '[Int, Double, Float] :: Constraint
-- = (Eq Int, (Eq Double, (Eq Float, () :: Constraint)))
我尝试使用 PolyKinds 对其进行概括。扩展如下。
{-# LANGUAGE DataKinds     #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}


type family All' (c :: k -> r) (xs :: [k]) :: r where
All' c '[] = ()
All' c (x ': xs) = (c x, All' c xs)

-- >>> :kind! All'
-- All' :: (k -> r) -> [k] -> r
-- = All'

--- This one works. Tuples of Types is a Type.
-- >>> :kind! All' Maybe '[Int, Double, Float]
-- All' Maybe '[Int, Double, Float] :: *
-- = (Maybe Int, (Maybe Double, (Maybe Float, ())))

--- However this one gets stuck.
-- >>> :kind! All' Eq '[Int, Double, Float]
-- All' Eq '[Int, Double, Float] :: Constraint
-- = All' Eq '[Int, Double, Float]
是那种 '(,) (a :: k) (b :: k)也一样 k .往下看似乎不是这样,所以我想知道为什么类型族定义 All' c (x ': xs) = (c x, All' c xs)一开始就被接受了(考虑到类型family return kind是 r)?
λ> :kind! '(,)
'(,) :: a -> b -> (a, b)
= '(,)

λ> :kind! '(,) ('True :: Bool) ('False :: Bool)
'(,) ('True :: Bool) ('False :: Bool) :: (Bool, Bool)
= '( 'True, 'False)
更新
正如@Daniel Wagner 在下面已经提到的 (,)这里使用的被认为是 Type -> Type -> Type和 kind 参数 r被实例化为 Type在上面的第二个等式( All' c (x ': xs) = (c x, All' c xs))内。事实上,如果我们使用 '(,) ,它会正确地返回一个类型错误。我能够使用技术 described in this blog post 进一步确认它。如下( All' 用种类 k* 实例化):
λ> :set -fprint-explicit-kinds
λ> :info All'
type All' :: forall k r. (k -> r) -> [k] -> r
type family All' @k @r c xs where
forall k (c :: k -> *). All' @k @(*) c ('[] @k) = ()
forall k (c :: k -> *) (x :: k) (xs :: [k]).
All' @k @(*) c ((':) @k x xs) = (c x, All' @k @(*) c xs)

最佳答案

这里有一个句法双关语。实际上有几种不同的逗号,有不同的种类:

 (,) :: Type -> Type -> Type
(,) :: Constraint -> Constraint -> Constraint -- ...ish
'(,) :: a -> b -> (a, b)
请注意,这些类型中没有一种与其他类型统一。此外,第二个有点谎言。如果 x :: Constrainty :: Constraint ,然后 (x, y) :: Constraint , 但逗号不能像 (,) x y 那样放在前缀.
在尝试消除前两个歧义时,GHC 假定您使用的是 (,) :: Type -> Type -> Type除非你在一个语法上不能使用它的地方(例如在 => 的左边)或者你已经给出了一个明确的类型注释 :: Constraint .单点 '消除前两个和最后一个之间的歧义。

关于haskell - 什么是多态/多类型元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68730280/

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