()作为空约束

时间:2018-05-09 20:38:45

标签: haskell constraint-kinds

如何表示空约束?

以下文件

{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE KindSignatures #-}

import Data.Kind(Type, Constraint)

type Empty = (() :: Type -> Constraint)

main :: IO ()
main = return ()

ghc 8.2.2答案

constraint.hs:6:15: error:
    • Expected kind ‘* -> Constraint’, but ‘()’ has kind ‘*’
    • In the type ‘(() :: Type -> Constraint)’
      In the type declaration for ‘Empty’
  |
6 | type Empty = (() :: Type -> Constraint)
  |  

我错过了什么?

我知道以下解决方案

{-# LANGUAGE FlexibleInstances #-}

class Empty x
instance Empty x

但我想知道为什么()不起作用

4 个答案:

答案 0 :(得分:5)

  

()*Constraint种,视情况而定,从不a -> Constraint。同样,(,)* -> * -> *Constraint -> Constraint -> Constraint种类,具体取决于具体情况。

     

- Simon Peyton-Jones

只是()只是因为它是类型还是约束而被重载。也就是说,你写的是() => a,而不是(() a) => a。所以我想这个:

class Empty x
instance Empty x

这是正确的解决方案吗? (也许这样的事情应该在base中。)

答案 1 :(得分:3)

()Constraint种,并不适用于Type

答案 2 :(得分:3)

Jon Purdy's answer是正确的。如果你想要一件事你可以拍打而不管arity(除了在一个实例头或类型族LHS中),你将需要使用一些样板:

{-# language PolyKinds, ConstraintKinds, FlexibleInstances,
    MultiParamTypeClasses, TypeFamilies #-}

import Data.Kind (Constraint)

class Unit1 a
instance Unit1 a
class Unit2 a b
instance Unit2 a b
...

type family Unit :: k
type instance Unit = (() :: Constraint)
type instance Unit = Unit1
type instance Unit = Unit2
...

然后

Prelude K> type Empty = (Unit :: Type -> Constraint)
Prelude K> :kind! Empty
Empty :: * -> Constraint
= Unit1

答案 3 :(得分:0)

根据您的需要,其中任何一种都可以正常工作:

in_progress