मैं संख्याओं को इस प्रकार का एक प्रकार देकर हास्केल में चर्च अंकों का अध्ययन करने की कोशिश कर रहा हूं, इस विचार के साथ कि प्राकृतिक संख्या n
मूल रूप से अभिव्यक्ति है जो निम्न प्रकार के फ़ंक्शन को मान पर लागू करती है बार के लिए t
टाइप करें।रैंकेंटाइप्स और चर्च अंक
zero :: Nat
zero = \f t -> t
succ :: Nat -> Nat
succ n = \f -> f . (n f)
plus :: Nat -> Nat -> Nat
plus m n = \f -> (m f) . (n f)
mult :: Nat -> Nat -> Nat
mult m n = \f -> m (n f) -- Equal to \f -> (m . n) f
-- Pointfree version
mult' :: Nat -> Nat -> Nat
mult' = (.)
जब मैं घातांक परिभाषित करने की कोशिश, मैं एक ही तर्क लागू करने की कोशिश करना चाहते हैं:
type Nat = forall t. (t -> t) -> t -> t
कि विचार के साथ
, मैं zero
, successor
, plus
, mult
निम्न तरीकों से परिभाषित कर सकते हैं जिसने मुझे गुणा को परिभाषित करने की अनुमति दी, अर्थात् mult m
n
बार 1
लागू करने की अनुमति दी।
यह निम्नलिखित कोड
exp' :: Nat -> Nat -> Nat
exp' m n = n (mult m) (succ zero)
की ओर जाता है लेकिन इस टाइप करता GHC से निम्न त्रुटि के साथ जांच:
Couldn't match type ‘t’ with ‘t1’
‘t’ is a rigid type variable bound by
the type signature for:
exp' :: forall t. Nat -> Nat -> (t -> t) -> t -> t
at church.lhs:44:3
‘t1’ is a rigid type variable bound by
a type expected by the context:
forall t1. (t1 -> t1) -> t1 -> t1
at church.lhs:44:17
Expected type: ((t -> t) -> t -> t) -> (t -> t) -> t -> t
Actual type: Nat -> Nat
त्रुटि कहना है कि typechecker के लिए प्रकार instantiating नहीं है लगता है n
ठीक से, t
टाइप करने के लिए अभिव्यक्ति के लिए अन्य 0 (t -> t
) के साथ तत्काल टाइप किया जाना चाहिए।
क्या भी भ्रमित कर रहा है मैं हूँ कि निम्नलिखित कोड typechecks:
exp :: Nat -> Nat -> Nat
exp m n = n ((.) m) (succ zero) -- replace mult by (.)
कोई मन को समझा सकते हैं कि समस्या क्या यहाँ है? exp'
की पहली परिभाषा टाइपशेक क्यों नहीं है लेकिन दूसरा exp
टाइपशेक्स क्यों है?
धन्यवाद!