如何表示空约束?
以下文件
{-# 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
但我想知道为什么()不起作用
答案 0 :(得分:5)
()
有*
或Constraint
种,视情况而定,从不a -> Constraint
。同样,(,)
有* -> * -> *
或Constraint -> Constraint -> Constraint
种类,具体取决于具体情况。
只是()
只是因为它是类型还是约束而被重载。也就是说,你写的是() => 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