तो मैं चर-लंबाई लंबाई टुपल्स के लिए एक प्रकार बनाने की कोशिश कर रहा हूं, मूल रूप से Either a (Either (a,b) (Either (a,b,c) ...))
और Either (Either (Either ... (x,y,z)) (y,z)) z
के एक सुंदर संस्करण के रूप में।जीएचसी: प्रेत प्रकार पैरामीटर का अनुमान लगाने में विफलता
{-# LANGUAGE TypeOperators, TypeFamilies, MultiParamTypeClasses, FlexibleInstances #-}
module Temp where
-- type level addition
data Unit
data Succ n
class Summable n m where
type Sum n m :: *
instance Summable Unit m where
type Sum Unit m = Succ m
instance Summable n m => Summable (Succ n) m where
type Sum (Succ n) m = Succ (Sum n m)
-- variable length tuple, left-to-right
data a :+ b = a :+ Maybe b
infixr 5 :+
class Prependable t r s where
type Prepend t r s :: *
prepend :: r -> Maybe s -> Prepend t r s
instance Prependable Unit x y where
type Prepend Unit x y = x :+ y
prepend = (:+)
instance Prependable n x y => Prependable (Succ n) (w :+ x) y where
type Prepend (Succ n) (w :+ x) y = w :+ Prepend n x y
prepend (w :+ Nothing) _ = w :+ Nothing
prepend (w :+ Just x) y = w :+ Just (prepend x y)
-- variable length tuple, right-to-left
data a :- b = Maybe a :- b
infixl 5 :-
class Appendable t r s where
type Append t r s :: *
append :: Maybe r -> s -> Append t r s
instance Appendable Unit x y where
type Append Unit x y = x :- y
append = (:-)
instance Appendable n x y => Appendable (Succ n) x (y :- z) where
type Append (Succ n) x (y :- z) = Append n x y :- z
append _ (Nothing :- z) = Nothing :- z
append x (Just y :- z) = Just (append x y) :- z
हालांकि, संकलक पुनरावर्ती मामलों में prepend
या append
का प्रेत प्रकार पैरामीटर का अनुमान लगा पाने में असमर्थ लगता है:
Temp.hs:32:40:
Could not deduce (Prepend t1 x y ~ Prepend n x y)
from the context (Prependable n x y)
bound by the instance declaration at Temp.hs:29:10-61
NB: `Prepend' is a type function, and may not be injective
In the return type of a call of `prepend'
In the first argument of `Just', namely `(prepend x y)'
In the second argument of `(:+)', namely `Just (prepend x y)'
Temp.hs:49:34:
Could not deduce (Append t0 x y ~ Append n x y)
from the context (Appendable n x y)
bound by the instance declaration at Temp.hs:46:10-59
NB: `Append' is a type function, and may not be injective
In the return type of a call of `append'
In the first argument of `Just', namely `(append x y)'
In the first argument of `(:-)', namely `Just (append x y)'
वहाँ है कुछ भी मैं संकलक मदद करने के लिए क्या कर सकते हैं इस निष्कर्ष बनाते हैं?
NB: `Prepend' is a type function, and may not be injective
इसका क्या मतलब है:
आह, मेरे लिए है कि त्रुटि संदेश के अर्थ बाहर चिढ़ा के लिए धन्यवाद। – rampion
ध्यान दें कि मूल कोड * करता है * प्रकार परिवारों का उपयोग करता है (विशेष रूप से, समानार्थी परिवार टाइप करें); इसका उपयोग डेटा परिवारों के बजाय करना चाहिए। – ehird
@ehird, मैंने हमेशा सोचा था कि "प्रकार के वर्गों में उपनाम टाइप करें" अभी भी परिवार के विस्तार के प्रकार से संबंधित नहीं है, लेकिन टीआईएल। – dflemstr