刚性类型和相等性检查 - 在Haskell中这是可能的吗?

时间:2018-03-14 23:23:04

标签: haskell types

想知道在Haskell中是否可以使用代码?

equal :: a -> b -> Bool
equal a b = a == b

2 个答案:

答案 0 :(得分:9)

不,(==)的类型要求其参数属于同一类型

(==) :: Eq a => a -> a -> Bool

你问是否可能(测试不同类型之间的平等),是的,这是可能的,但不是你通常做的事情。您可以使用Typeable来证明ab属于同一类型,但您需要Typeable约束{和Eq约束)

{-# Language ScopedTypeVariables #-}
{-# Language TypeApplications    #-}
{-# Language ConstraintKinds     #-}
{-# Language GADTs               #-}

import Type.Reflection

type Equal a b = (Eq a, Typeable a, Typeable b)

equal :: forall a b. Equal a b => a -> b -> Bool
equal x y =
  case eqTypeRep (typeRep @a) (typeRep @b) of
    -- In this branch, `a' and `b' are the SAME type
    -- so `(==)' works
    Just HRefl -> x == y

    -- Values of different types are never equal
    Nothing -> False

所以以下工作

>> equal 10 'a'
False
>> equal 'X' 'a'
False
>> equal 'X' 'X'
True

请务必理解为什么我们只约束Eq a / Eq b中的一个,并不重要。

答案 1 :(得分:3)

尽管事件Eq不允许您根据==签名定义该功能,但您可以定义自己的类型类:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}

class Eqq a b where
  eqq :: a -> b -> Bool

-- Just an example of a possible instance for general types
instance Eqq a b where
  eqq a b = True 

然后,

equal :: (Eqq a b) => a -> b -> Bool
equal a b = a `eqq` b