2017-04-14 13 views
5

मान लीजिए मैं प्रकार की एक सूची की तरह [*] है,: तो अब तकबहुरूपी कार्यों

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))) 

मैं आस-पास काम कर सकते हैं यह किसी भी तरह से?

+0

क्यों नहीं 'बीएस = forall z के रूप में मज़ा टाइप करें। जेड के रूप में tupled -> tupled बीएस z'? –

+0

@ ली-याओएक्सिया: मैं 'फन' को 'फन' के लिए तर्क के रूप में पास करने में सक्षम होना चाहता हूं, इसलिए मुझे अपर्याप्तता को छिपाने के लिए 'newtype' की आवश्यकता है। –

उत्तर

4

AllowAmbiguousTypes सक्षम करें। जीएचसी 8 से, अस्पष्टता जांच पूरी तरह से अनिवार्य है, क्योंकि किसी भी (मौलिक रूप से हल करने योग्य) अस्पष्टता को प्रकार के अनुप्रयोगों के साथ हल किया जा सकता है। इसके अलावा, आपका मामला अस्पष्टता जांच के लिए सिर्फ एक झूठा सकारात्मक प्रतीत होता है, क्योंकि हम बिना किसी प्रकार के अनुप्रयोगों के Fun का स्पष्ट रूप से उपयोग कर सकते हैं।

+0

मुझे इस प्रश्न में यह ध्यान देना चाहिए था, लेकिन ऐसा करने में कोई फर्क नहीं पड़ता-मुझे एक ही त्रुटि संदेश मिलता है। मैं 'एलटीएस -8.9' स्टैक रिज़ॉल्वर से जीएचसी 8.0.2 का उपयोग कर रहा हूं। –

+0

यह [फ़ाइल] (http://lpaste.net/354579) दोनों जीएचसी 8.0.1 और 8.0.2 दोनों द्वारा स्वीकार किया जाता है। मुझे यकीन नहीं है कि आपकी तरफ क्या गलत है (इसके अलावा, मैंने बंद प्रकार का familiy इस्तेमाल किया लेकिन खुले काम भी)। –

+1

आह, 'newtype Fun bs = Fun (forall z। ...) 'टाइपशेक, लेकिन' ... = Fun {unfun :: forall z। ...} नहीं है। मैं उलझन में था क्योंकि 'unfun' की * परिभाषा * को एक अस्पष्ट * उपयोग साइट * माना जाता है। इसे एक अलग फ़ंक्शन बनाना और एक प्रकार का अनुप्रयोग 'unfun :: forall bs z के रूप में उपयोग करना। बीएस के रूप में मज़ा -> जेड के रूप में tupled -> tupled बीएस जेड; unfun (Fun f) के रूप में = f @z के रूप में समस्या हल करती है। मुझे यह समझने में मदद करने के लिए धन्यवाद। :) –

संबंधित मुद्दे