5

संपादित करें में त्वरित प्रकार परिवर्तक संपादित करें: हल किया गया। मुझे पता नहीं था कि स्रोत फ़ाइल में भाषा विस्तार को सक्षम करने से जीएचसीआई में भाषा विस्तार सक्षम नहीं हुआ है। समाधान जीएचसीआई में :set FlexibleContexts था।हास्केल


मुझे हाल ही में पता चला है कि हास्केल में कक्षाओं और उदाहरणों में प्रकार की घोषणा हॉर्न क्लॉज हैं। इसलिए मैंने अंकगणितीय परिचालन को से आर्ट ऑफ़ प्रोलॉग, अध्याय 3, हास्केल में एन्कोड किया। उदाहरण के लिए:

fac(0,s(0)). 
fac(s(N),F) :- fac(N,X), mult(s(N),X,F). 

class Fac x y | x -> y 
instance Fac Z (S Z) 
instance (Fac n x, Mult (S n) x f) => Fac (S n) f 

pow(s(X),0,0) :- nat(X). 
pow(0,s(X),s(0)) :- nat(X). 
pow(s(N),X,Y) :- pow(N,X,Z), mult(Z,X,Y). 

class Pow x y z | x y -> z 
instance (N n) => Pow (S n) Z Z 
instance (N n) => Pow Z (S n) (S Z) 
instance (Pow n x z, Mult z x y) => Pow (S n) x y 

प्रोलॉग में, मूल्यों को (तर्क) चर के लिए तत्काल में तत्काल किया जाता है। हालांकि, मुझे समझ में नहीं आता कि हास्केल में टाइप वैरिएबल को कैसे चालू किया जाए। यही है, मुझे समझ में नहीं आता है कि हास्केल प्रोलॉग क्वेरी

?-f(X1,X2,...,Xn) 

है। मुझे लगता है कि

:t undefined :: (f x1 x2 ... xn) => xi 

हास्केल xi का दृष्टांत कर सकता है, लेकिन यह एक Non type-variable argument in the constraint त्रुटि देता है, यहां तक ​​कि FlexibleContexts सक्षम के साथ।

+2

ध्यान रखें कि यह हैकेल के प्रकार सिस्टम में प्रोलॉग एम्बेड नहीं करता है। टाइपक्लास सॉल्वर * बैकट्रैकिंग * नहीं करता है। – luqui

+0

आप सही हैं; हालांकि, मैं किसी भी प्रभाव के तहत नहीं था कि यह किया था। एक वास्तविक एम्बेडिंग के लिए और अधिक काम की आवश्यकता होगी :)। – danportin

उत्तर

3

Prolog नमूने के बारे में नहीं यकीन है, लेकिन मैं निम्नलिखित तरीके से हास्केल में यह निर्धारित करना होगा:

{-# LANGUAGE MultiParamTypeClasses, EmptyDataDecls, FlexibleInstances, 
FlexibleContexts, UndecidableInstances, TypeFamilies, ScopedTypeVariables #-} 

data Z 
data S a 
type One = S Z 
type Two = S One 
type Three = S Two 
type Four = S Three 


class Plus x y r 
instance (r ~ a) => Plus Z a r 
instance (Plus a b p, r ~ S p) => Plus (S a) b r 

p1 = undefined :: (Plus Two Three r) => r 


class Mult x y r 
instance (r ~ Z) => Mult Z a r 
instance (Mult a b m, Plus m b r) => Mult (S a) b r 

m1 = undefined :: (Mult Two Four r) => r 


class Fac x r 
instance (r ~ One) => Fac Z r 
instance (Fac n r1, Mult (S n) r1 r) => Fac (S n) r 

f1 = undefined :: (Fac Three r) => r 


class Pow x y r 
instance (r ~ One) => Pow x Z r 
instance (r ~ Z) => Pow Z y r 
instance (Pow x y z, Mult z x r) => Pow x (S y) r 

pw1 = undefined :: (Pow Two Four r) => r 

-- Handy output 
class (Num n) => ToNum a n where 
    toNum :: a -> n 
instance (Num n) => ToNum Z n where 
    toNum _ = 0 
instance (ToNum a n) => ToNum (S a) n where 
    toNum _ = 1 + toNum (undefined :: a) 

main = print $ (toNum p1, toNum m1, toNum f1, toNum pw1) 

अद्यतन:

danportin रूप TypeFamilies "लेज़ी पैटर्न" नीचे उसकी टिप्पणी में बताया गया है (उदाहरण के संदर्भ में) यहां जरूरी नहीं है (उसका प्रारंभिक कोड छोटा और अधिक क्लीनर है)।

एक इस पद्धति हालांकि, जो मैं इस सवाल के संदर्भ में सोच सकते हैं के आवेदन यह है: हम अपने प्रकार स्तरीय गणित को बूलियन तर्क जोड़ना चाहते हैं कहते हैं:

data HTrue 
data HFalse 

-- Will not compile 
class And x y r | x y -> r 
instance And HTrue HTrue HTrue 
instance And a b HFalse -- we do not what to enumerate all the combination here - they all HFalse 

लेकिन यह नहीं होगा "कार्यात्मक निर्भरता संघर्ष" के कारण संकलित करें। और यह मेरे लिए लग रहा है कि हम अभी भी fundeps के बिना इस अतिव्यापी मामले को व्यक्त कर सकते हैं:

class And x y r 
instance (r ~ HTrue) => And HTrue HTrue r 
instance (r ~ HFalse) => And a b r 

b1 = undefined :: And HTrue HTrue r => r -- HTrue 
b2 = undefined :: And HTrue HFalse r => r -- HFalse 

यह निश्चित रूप से एक सबसे अच्छा तरीका है (यह IncoherentInstances की आवश्यकता है) नहीं है। तो शायद कोई दूसरा, कम 'दर्दनाक' दृष्टिकोण सुझा सकता है।

+1

मुझे यकीन नहीं है कि आलसी पैटर्न मैच का उद्देश्य क्या है। मुझे और पढ़ना होगा। मुझे पता नहीं था कि स्रोत फ़ाइल में भाषा एक्सटेंशन सक्षम करने से जीएचसीआई में उन (सक्षम) एक्सटेंशन सक्षम नहीं हुए। तो समाधान उनके साथ व्याख्या करने के अलावा 'फ्लेक्सिबल कॉन्टैक्स' सेट करना था। धन्यवाद, हालांकि। – danportin

+2

@ डैनपोर्टिन, हाँ, मैं सहमत हूं - यह "आलसी पैटर्न" की आवश्यकता नहीं थी। मैं इसे प्रतिबिंबित करने के लिए अपनी पोस्ट संपादित करूंगा। मुझे लगता है कि जब हम ओवरलैपिंग इंस्टेंस स्थिति का सामना करते हैं तो यह पटर उपयोगी होगा (अन्यथा हम कार्यात्मक निर्भरता संघर्ष प्राप्त करेंगे)। प्रकार-स्तर का मेरा उदाहरण देखें और –