संघनन के बारे में एक अच्छा सच यह है कि अगर मुझे समीकरण में कोई दो चर पता हैं:
a ++ b = c
फिर मैं तीसरा जानता हूं।
मैं इस विचार को अपने स्वयं के संगीत कार्यक्रम में कैद करना चाहता हूं इसलिए मैं एक कार्यात्मक निर्भरता का उपयोग करता हूं।
{-# Language DataKinds, GADTs, FlexibleContexts, FlexibleInstances, FunctionalDependencies, KindSignatures, PolyKinds, TypeOperators, UndecidableInstances #-}
import Data.Kind (Type)
class Concatable
(m :: k -> Type)
(as :: k)
(bs :: k)
(cs :: k)
| as bs -> cs
, as cs -> bs
, bs cs -> as
where
concat' :: m as -> m bs -> m cs
अब मैं इस तरह से विषम सूची को आकर्षित करता हूं:
data HList ( as :: [ Type ] ) where
HEmpty :: HList '[]
HCons :: a -> HList as -> HList (a ': as)
लेकिन जब मैं इन्हें घोषित करने की कोशिश करता Concatable
हूं क्योंकि मेरे पास एक मुद्दा है
instance Concatable HList '[] bs bs where
concat' HEmpty bs = bs
instance
( Concatable HList as bs cs
)
=> Concatable HList (a ': as) bs (a ': cs)
where
concat' (HCons head tail) bs = HCons head (concat' tail bs)
मैं अपने तीसरे कार्यात्मक निर्भरता को संतुष्ट नहीं करता हूं। या बल्कि संकलक का मानना है कि हम नहीं करते हैं। ऐसा इसलिए है क्योंकि कंपाइलर का मानना है कि हमारे दूसरे उदाहरण में ऐसा हो सकता है bs ~ (a ': cs)
। और अगर ऐसा हो सकता है Concatable as (a ': cs) cs
।
मैं अपने उदाहरणों को कैसे समायोजित कर सकता हूं ताकि सभी तीन निर्भरताएं संतुष्ट हों?
bs
और cs
, और हम फंड का फायदा उठाना चाहते हैं, यानी हम पुनर्निर्माण करना चाहते हैं as
। नियत तरीके से करने के लिए, हम एक उदाहरण के लिए प्रतिबद्ध होने और उस नुस्खा का पालन करने में सक्षम होने की उम्मीद करते हैं। लगातार, मान bs = (Int ': bs2)
और cs = (Int ': cs2)
। हम कौन सा उदाहरण चुनते हैं? यह संभव है कि इस तरह Int
से cs
आता है bs
(और as
खाली है)। यह भी संभव है कि as
इसके बजाय (nonempty) से आता है , और बाद Int
में फिर से दिखाई देगा cs
। हमें यह जानने के लिए और खुदाई करने की आवश्यकता है cs
कि GHC ऐसा नहीं करेगा।
bs cs -> as
, क्योंकि हमें गैर-स्थानीय जानकारी की आवश्यकता हैbs
औरcs
यह तय करने के लिए कि क्याas
विपक्ष या शून्य होना चाहिए। हमें यह पता लगाने की आवश्यकता है कि इस जानकारी का प्रतिनिधित्व कैसे करें; जब हम सीधे कटौती नहीं कर सकते हैं, तो हम इसकी गारंटी देने के लिए किस प्रकार के हस्ताक्षर को जोड़ेंगे?