为什么此约束在这些单独的实例中具有不同的行为?

时间:2018-07-31 15:23:56

标签: haskell types type-families type-level-computation

我做了两个类型家族:

PowerApps Custom Visual

现在,我想结合两个类型族,以检查类型级别列表中的所有成员是否都是Mays。这是我的处理方式:

{-# Language KindSignatures, DataKinds, TypeOperators, TypeFamilies, FlexibleContexts #-}

import Data.Kind

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

type family Is (f :: Type -> Type) (x :: Type) :: Constraint where
  Is f (f _) = ()

现在,如果我尝试使用以下方法对此进行测试:

All (Is Maybe) tList

我收到编译错误:

f :: (All (Is Maybe) '[Maybe Bool]) => a -> a
f = id

基于此,我认为我会缺少[1 of 1] Compiling Main ( familyTest.hs, interpreted ) familyTest.hs:12:6: error: • The type family ‘Is’ should have 2 arguments, but has been given 1 • In the type signature: f :: (All (Is Maybe) '[Maybe Bool]) => a -> a | 12 | f :: (All (Is Maybe) '[Maybe Bool]) => a -> a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded. 的论点。我的第一个想法是这与curring有关。也许类型家庭缺乏部分应用。但是,当我去弄清楚我错过了什么时,会发生一些奇怪的事情。首先,我检查所有基本组件的种类:

Is

这里没有任何问题,所以我开始将它们放在一起:

[1 of 1] Compiling Main             ( familyTest.hs, interpreted )
Ok, one module loaded.
*Main> :k All
All :: (* -> Constraint) -> [*] -> Constraint
*Main> :k Is
Is :: (* -> *) -> * -> Constraint
*Main> :k Maybe
Maybe :: * -> *
*Main> :k Bool
Bool :: *

这有点奇怪,*Main> :k Is Maybe Is Maybe :: * -> Constraint 的类型为Is Maybe。我可以预料到这一点,但是先前的错误告诉我我在Type -> Constraint中输入了错误的参数数量。现在,我们尝试将其传递给Is

All

令人惊讶的是,即使我们希望这样做,它也不会出错。最后要尝试的是完成约束:

*Main> :k All (Is Maybe)
All (Is Maybe) :: [*] -> Constraint

并且它起作用了,尽管编译器早些时候抱怨这个确切的语句,但是现在该语句似乎是一个有效的约束。编译原始代码时,仍然出现相同的错误。

因此,在这一点上,我开始简化代码,以便可以隔离行为。

*Main> :k All (Is Maybe) '[Maybe Bool]
All (Is Maybe) '[Maybe Bool] :: Constraint

这仍然会导致类似的错误:

type family App (c :: Type -> Constraint) (x :: Type) :: Constraint where
  App c x = c x

type family IsBool (x :: Type) :: Constraint where
  IsBool Bool = ()

f :: (App IsBool Bool) => a -> a
f = id

当我尝试使用[1 of 1] Compiling Main ( familyTest.hs, interpreted ) familyTest.hs:19:6: error: • The type family ‘IsBool’ should have 1 argument, but has been given none • In the type signature: f :: (App IsBool Bool) => a -> a | 19 | f :: (App IsBool Bool) => a -> a | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Failed, no modules loaded.

检查时没有显示
:k

这是怎么回事?

0 个答案:

没有答案