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