Featured post
prolog - Instantiate type variable in Haskell -
edit: solved. unware enabling language extension in source file did not enable language extension in ghci. solution :set flexiblecontexts
in ghci.
i discovered type declarations in classes , instances in haskell horn clauses. encoded arithmetic operations the art of prolog, chapter 3, haskell. instance:
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
in prolog, values instantiated (logic) variable in proof. however, don't understand how instantiate type variables in haskell. is, don't understand haskell equivalent of prolog query
?-f(x1,x2,...,xn)
is. assume that
:t undefined :: (f x1 x2 ... xn) => xi
would cause haskell instantiate xi
, gives non type-variable argument in constraint
error, flexiblecontexts
enabled.
no sure prolog samples, define in haskell in following way:
{-# language multiparamtypeclasses, emptydatadecls, flexibleinstances, flexiblecontexts, undecidableinstances, typefamilies, scopedtypevariables #-} data z data s type 1 = s z type 2 = s 1 type 3 = s 2 type 4 = s 3 class plus x y r instance (r ~ a) => plus z r instance (plus b p, r ~ s p) => plus (s a) b r p1 = undefined :: (plus 2 3 r) => r class mult x y r instance (r ~ z) => mult z r instance (mult b m, plus m b r) => mult (s a) b r m1 = undefined :: (mult 2 4 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 3 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 2 4 r) => r -- handy output class (num n) => tonum n tonum :: -> n instance (num n) => tonum z n tonum _ = 0 instance (tonum n) => tonum (s a) n tonum _ = 1 + tonum (undefined :: a) main = print $ (tonum p1, tonum m1, tonum f1, tonum pw1)
update:
as danportin noted in comment below typefamilies "lazy pattern" (in instance context) not needed here (his initial code shorter , cleaner).
one application of pattern though, can think of in context of question this: want add boolean logic our type-level arithmetic:
data htrue data hfalse -- not compile class , x y r | x y -> r instance , htrue htrue htrue instance , b hfalse -- not enumerate combination here - hfalse
but not compile due "functional dependencies conflict". , looks me still can express overlapping case without fundeps:
class , x y r instance (r ~ htrue) => , htrue htrue r instance (r ~ hfalse) => , b r b1 = undefined :: , htrue htrue r => r -- htrue b2 = undefined :: , htrue hfalse r => r -- hfalse
it's not nicest way (it requires incoherentinstances). maybe can suggest another, less 'traumatic' approach.
- Get link
- X
- Other Apps
Comments
Post a Comment