मान लीजिए मैं प्रकार की एक सूची की तरह [*]
है,: तो अब तकबहुरूपी कार्यों
type family Tupled (ts :: [*]) z :: *
type instance Tupled (t ': ts) z = (t, Tupled ts z)
type instance Tupled '[] z = z
:
let Ts = '[Int, Bool, Char]
मैं tuples की एक श्रृंखला को यह परिवर्तित करना चाहते हैं अच्छा:
> :kind! Tupled Ts()
Tupled Ts() :: *
= (Int, (Bool, (Char,())))
अब मैं एक प्रकार Fun
कार्यों का प्रतिनिधित्व करने के लिखने में सक्षम होना चाहते हैं कि इस श्रृंखला के "नीचे" में polymorphic हैं। उदाहरण के लिए, Fun Ts Ts
इन प्रकार के दोनों पर काम करना चाहिए:
(Int, (Bool, (Char, (String,()))))
(Int, (Bool, (Char, (Word, (ByteString,())))))
मैं इस कोशिश की:
newtype Fun as bs = Fun
{ unfun :: forall z. Tupled as z -> Tupled bs z }
लेकिन यह typecheck करने में विफल रहता:
Couldn't match type ‘Tupled bs z’ with ‘Tupled bs z0’
NB: ‘Tupled’ is a type function, and may not be injective
The type variable ‘z0’ is ambiguous
Expected type: Tupled as z -> Tupled bs z
Actual type: Tupled as z0 -> Tupled bs z0
In the ambiguity check for the type of the constructor ‘Fun’:
Fun :: forall z. Tupled as z -> Tupled bs z
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the definition of data constructor ‘Fun’
In the newtype declaration for ‘Fun’
मैं उपयोग करने के लिए सिफारिशों को देखा है इंजेक्शन के साथ समस्याओं से बचने के लिए एक डेटा परिवार:
data family Tupled (ts :: [*]) z :: *
data instance Tupled (t ': ts) z = Cons t (Tupled ts z)
data instance Tupled '[] z = Nil
और वास्तव में है कि Fun
संकलन करता है, लेकिन यह Cons
और Nil
की भूमि में लग रहा है कि मुझे हो जाता है की तरह "अटक जाने" जब मैं इस तरह, tuples के साथ काम करने के लिए देख रहा हूँ:
Fun $ \ (i, (b, (c, z))) -> (succ i, (not b, (pred c, z)))
मैं आस-पास काम कर सकते हैं यह किसी भी तरह से?
क्यों नहीं 'बीएस = forall z के रूप में मज़ा टाइप करें। जेड के रूप में tupled -> tupled बीएस z'? –
@ ली-याओएक्सिया: मैं 'फन' को 'फन' के लिए तर्क के रूप में पास करने में सक्षम होना चाहता हूं, इसलिए मुझे अपर्याप्तता को छिपाने के लिए 'newtype' की आवश्यकता है। –