() как пустое ограничение
Как можно представить пустое ограничение?
для следующего файла
{-# 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 ответа
()
имеет вид*
или жеConstraint
в зависимости от контекста, никогдаa -> Constraint
, так же(,)
имеет вид* -> * -> *
или жеConstraint -> Constraint -> Constraint
в зависимости от контекста.
Это просто ()
перегружается только для типа или ограничения. То есть ты бы написал () => a
не (() a) => a
, Так что я думаю это:
class Empty x
instance Empty x
Это правильное решение здесь. (И, возможно, что-то подобное должно быть в base
.)
Ответ Джона Перди правильный. Если вам нужна одна вещь, которую вы можете использовать независимо от арности (за исключением главы экземпляра или семейства типов 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
()
имеет вид Constraint
и не предназначен для применения к Type
,
Любой из них работает нормально, в зависимости от того, что вы хотите:
type Empty = (() :: Constraint)
type ConstEmpty x = (() :: Constraint)