Type of automatic conversion to haskell

I wrote some useful functions for performing a logical operation. He looks like (a and b or c) `belongs` x.

Thanks Num, IsListand OverloadedListsI can use it for integers and lists.

λ> (1 && 2 || 3) `belongs` [2]
False
λ> (1 && 2 || 3) `belongs` [1, 2]
True
λ> (1 && 2 || 3) `belongs` [3]
True

λ> :set -XOverloadedLists
λ> ([1, 2] && [2, 3] || [3, 4]) `contains` 1
False
λ> ([1, 2] && [2, 3] || [3, 4]) `contains` 2
True

I do like this:

newtype BoolLike a = BoolLike ((a -> Bool) -> Bool)

(&&) :: BoolLike a -> BoolLike a -> BoolLike a
BoolLike f && BoolLike g = BoolLike $ \k -> f k P.&& g k
infixr 3 &&

toBoolLike :: a -> BoolLike a
toBoolLike x = BoolLike $ \k -> k x

belongs :: Eq a => BoolLike a -> [a] -> Bool
belongs (BoolLike f) xs = f (\x -> x `elem` xs)

contains :: Eq a => BoolLike [a] -> a -> Bool
contains (BoolLike f) x = f (\xs -> x `elem` xs)

instance Num a => Num (BoolLike a) where
  fromInteger = toBoolLike . fromInteger

What I'm going to do is make it suitable for any type, without manually converting ato BoolLike a.

How can i achieve this?

First try:

class IsBool a where
  type BoolItem a
  toBool :: a -> BoolItem a

instance IsBool (BoolLike a) where
  type BoolItem (BoolLike a) = BoolLike a
  toBool = id

instance IsBool a where
  type BoolItem a = BoolLike a
  toBool = toBoolLike

Failed:

Conflicting family instance declarations:
  BoolItem (BoolLike a) -- Defined at BoolLike.hs:54:8
  BoolItem a -- Defined at BoolLike.hs:58:8
+4
source share
2 answers

You can try this

type family BoolItem a where
    BoolItem (BoolLike a) = BoolLike a
    BoolItem a = BoolLike a

class IsBool a where
  toBool :: a -> BoolItem a

instance IsBool (BoolLike a) where
  toBool = id

instance (BoolItem a ~ BoolLike a) => IsBool a where
  toBool = toBoolLike

, . , , . , OVERLAPPABLE

+3

, , , , , , , , . , , , , - , , , .

, BoolLike a...

newtype BoolLike a = BoolLike ((a -> Bool) -> Bool)

... , Bool a -> Bool. Bool (&&) (||) . Applicative ( (->) (a -> Bool)) (&)/flip ($), (a -> Bool) -> Bool " ":

GHCi> ((||) <$> ((&&) <$> ($ 1) <*> ($ 2)) <*> ($ 3)) (`elem` [2])
False

, , , . , :

(<&&>) :: Applicative f => f Bool -> f Bool -> f Bool
x <&&> y = (&&) <$> x <*> y

(<||>) :: Applicative f => f Bool -> f Bool -> f Bool
x <||> y = (||) <$> x <*> y

( , , control-bool.)

, :

GHCi> (($ 1) <&&> ($ 2) <||> ($ 3)) (`elem` [2])
False

contains - , , :

GHCi> (($ [1, 2]) <&&> ($ [2, 3]) <||> ($ [3, 4])) (elem 1)
False

, , contains intersect union Data.List:

GHCi> [1, 2] `intersect` [2, 3] `union` [3, 4] & elem 1
False
+3

Source: https://habr.com/ru/post/1659244/


All Articles