简体   繁体   English

()作为空约束

[英]() as empty constraint

how can one represent the empty constraint ? 怎么能代表空约束呢?

for the following file 对于以下文件

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

import Data.Kind(Type, Constraint)

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

main :: IO ()
main = return ()

ghc 8.2.2 answers 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)
  |  

what do i miss ? 我想念什么?

i know about the following solution 我知道以下解决方案

{-# LANGUAGE FlexibleInstances #-}

class Empty x
instance Empty x

but i want to know why () does not work 但我想知道为什么()不起作用

() has kind * or Constraint , depending on context, never a -> Constraint . ()具有kind *Constraint ,具体取决于上下文,从不a -> Constraint Similarly (,) has kind * -> * -> * or Constraint -> Constraint -> Constraint , depending on context. 类似地(,)具有种类* -> * -> *Constraint -> Constraint -> Constraint ,具体取决于上下文。

Simon Peyton-Jones - 西蒙佩顿琼斯

It's just that () is only overloaded for whether it's a type or a constraint. 只是()只是因为它是一个类型或一个约束而被重载。 That is, you'd write () => a , not (() a) => a . 也就是说,你写() => a ,而不是(() a) => a So I think this: 所以我想这个:

class Empty x
instance Empty x

Is the correct solution here. 这是正确的解决方案。 (And perhaps something like that should be in base .) (也许这样的事情应该是base 。)

()具有种类Constraint ,并不适用于Type

Jon Purdy's answer is correct. Jon Purdy的回答是正确的。 If you want one thing you can slap in regardless of arity (except in an instance head or type family LHS), you're going to need to use some boilerplate: 如果你想要一件东西,无论是否为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
...

Then 然后

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

Either of these work fine, depending on what you want: 根据你的需要,这些都可以正常工作:

type Empty = (() :: Constraint)
type ConstEmpty x = (() :: Constraint)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM