सबसे पहले, कुछ बॉयलरप्लेट:
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE UndecidableInstances, UndecidableSuperClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ScopedTypeVariables #-}
module ConstrainApplications where
import GHC.Exts (Constraint)
import Data.Type.Equality
अब मनमाना प्रकार पर अनुप्रयोगों deconstruct करने के लिए परिवारों टाइप करें।
type family GetFun a where
GetFun (f _) = f
type family GetArg a where
GetArg (_ a) = a
अब एक अत्यंत सामान्य प्रकार का कार्य, प्रश्न का उत्तर देने के लिए आवश्यक से अधिक सामान्य है। लेकिन यह एप्लिकेशन के दोनों घटकों को शामिल करने वाली बाधा की अनुमति देता है।
type G (cfa :: (j -> k) -> j -> Constraint) (fa :: k)
= (fa ~ (GetFun fa :: j -> k) (GetArg fa :: j)
, cfa (GetFun fa) (GetArg fa))
मैं वर्गों मैच के लिए बिना बाधा कार्यों की पेशकश, इसलिए यहाँ पसंद नहीं है G
की एक प्रथम श्रेणी संस्करण है। कुछ नमूना F
का उपयोग करता
class (cf f, ca a) => Q cf ca f a
instance (cf f, ca a) => Q cf ca f a
type F cf ca fa = G (Q cf ca) fa
class F cf ca fa => FC cf ca fa
instance F cf ca fa => FC cf ca fa
यहाँ हैं::
class G cfa fa => GC cfa fa
instance G cfa fa => GC cfa fa
यह G
और एक सहायक वर्ग का उपयोग कर F
व्यक्त करने के लिए संभव है
t1 :: FC ((~) Maybe) Eq a => a -> a -> Bool
t1 = (==)
-- In this case, we deconstruct the type *twice*:
-- we separate `a` into `e y`, and then separate
-- `e` into `Either x`.
t2 :: FC (FC ((~) Either) Show) Show a => a -> String
t2 x = case x of Left p -> show p
Right p -> show p
t3 :: FC Applicative Eq a => a -> a -> GetFun a Bool
t3 x y = (==) <$> x <*> y
अगर आप एक inflix के रूप में एफसी का उपयोग यह बेहतर लग रहा है ऑपरेटर। – 2426021684
'((~) या तो) \' एफसी \ 'ईक \' एफसी \ 'ईक' – 2426021684
@ 2426021684, अच्छा बिंदु। – dfeuer