type families - Haskell: Function to apply some function to nested 2-tuples -
say have tuple ('a',(1,("hello",false)). fun (read: learning), i'd create function applies function of correct form such tuple , returns result. example usage:
applyfntotuple ('o',('t','w')) $ \a b c -> [a,b,c] == "otw" applyfntotuple ('h','i') $ \a b -> [a,b] == "hi" applyfntotuple ("hello",('y','o')) $ \a b c -> ++ [b,c] i've done of follows:
type family tuplefn ty out tuplefn (a,b) output = -> (tuplefn b output) tuplefn b output = b -> output class applyfntotuple applyfntotuple :: -> tuplefn out -> out instance applyfntotuple b => applyfntotuple (a,b) applyfntotuple (a,b) fn = applyfntotuple b (fn a) instance applyfntotuple applyfntotuple b fn = fn b the sticking point last instance. expect need add {-# overlappable #-} since a more general (a,b). struggle see how ghc resolve a , correct version of tuplefn class , know correct type sig, can put down own lack of understanding. in case, actual error ghci gives me is:
couldn't match expected type ‘a -> out’ actual type ‘tuplefn out’ relevant bindings include fn :: tuplefn out (bound @ examples.hs:574:22) b :: (bound @ examples.hs:574:20) applyfntotuple :: -> tuplefn out -> out (bound @ examples.hs:574:5) function ‘fn’ applied 1 argument, type ‘tuplefn out’ has none in expression: fn b in equation ‘applyfntotuple’: applyfntotuple b fn = fn b failed, modules loaded: none. as far can see, no version of tuplefn returns no arguments, don't understand error. however, find can made compile changing last instance more concrete eg:
instance applyfntotuple char applyfntotuple b fn = fn b but means i'd have define lots of similar instances etc undesirable.
what i'd know is, there relatively easy way make more general version work, , why particular error?
thankyou :)
ps: i'm running ghc 7.10.1
the problem within definition of instance applyfntotuple a, there no access information a isn't tuple - guess ghc doesn't consider how instance might chosen in deciding whether correct definition. means cannot know tuplefn gives right result use, , instance doesn't typecheck.
to fix this, can add equational constraint tell tuplefn correct. unfortunately since constraint has mention out type, requires including type parameter class. @ least, following seems work (tested ghc 7.8 only):
{-# language typefamilies, flexibleinstances, multiparamtypeclasses, overlappinginstances #-} type family tuplefn ty out tuplefn (a,b) output = -> (tuplefn b output) tuplefn b output = b -> output class applyfntotuple out applyfntotuple :: -> tuplefn out -> out instance applyfntotuple b out => applyfntotuple (a,b) out applyfntotuple (a,b) fn = applyfntotuple b (fn a) instance tuplefn out ~ (a -> out) => applyfntotuple out applyfntotuple b fn = fn b
Comments
Post a Comment