distinguish functions from non-functions in a class/instances

Hello, i'm trying to wrap functions (a -> b -> ... -> z) of any arity to functions of type ([String] -> y), where list of strings replaces the typed arguments. one attempt looks like this (here written with type families, you can replace it by functional dependencies or what ever): type family Res x type instance Res x = x type instance Res (x->y) = Res y class Nary x where nary :: x -> [String] -> Res x instance Nary x where nary x [] = x instance Nary (x->y) where nary f (x:xs) = nary (f $ read x) xs i hope you can get the idea. the problem is, that you cannot distinguish type (x->y) from z, so these instances are overlapping. the odd thing is. you can get this to work, if you have a terminating type as result type (for example (IO x)). then you can work with all types (IO x), (a -> IO x), (a -> b -> IO x), ... but i don't want this delimiter IO! any ideas? greetings Philipp N. -- View this message in context: http://www.nabble.com/distinguish-functions-from-non-functions-in-a-class-in... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Dec 5, 2007, at 16:00 , Philipp N. wrote:
the odd thing is. you can get this to work, if you have a terminating type as result type (for example (IO x)). then you can work with all types (IO x), (a -> IO x), (a -> b -> IO x), ...
but i don't want this delimiter IO! any ideas?
Use ST instead? (just tossing ideas in the wind...) -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH

Wouldn't any isomorphism do (like the Identity monad)? How about nary' f = runIdentity . nary (liftM f) . return Brandon S. Allbery KF8NH wrote:
On Dec 5, 2007, at 16:00 , Philipp N. wrote:
the odd thing is. you can get this to work, if you have a terminating type as result type (for example (IO x)). then you can work with all types (IO x), (a -> IO x), (a -> b -> IO x), ...
but i don't want this delimiter IO! any ideas?
Use ST instead? (just tossing ideas in the wind...)

No, that doesn't work; it's close, but not quite. liftM doesn't have the
right type signature.
liftM :: Monad m => (a -> r) -> (m a1 -> m r)
What would work is if you could define a function
liftLast :: Monad m => (a0 -> a1 -> ... -> aN -> r) -> (a0 -> a1 -> ... ->
aN -> m r)
then
nary' f = runIdentity . nary (liftLast f)
-- ryan
On 12/5/07, Dan Weston
Wouldn't any isomorphism do (like the Identity monad)? How about
nary' f = runIdentity . nary (liftM f) . return
Brandon S. Allbery KF8NH wrote:
On Dec 5, 2007, at 16:00 , Philipp N. wrote:
the odd thing is. you can get this to work, if you have a terminating type as result type (for example (IO x)). then you can work with all types
(IO
x), (a -> IO x), (a -> b -> IO x), ...
but i don't want this delimiter IO! any ideas?
Use ST instead? (just tossing ideas in the wind...)
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Ryan Ingram wrote:
No, that doesn't work; it's close, but not quite. liftM doesn't have the right type signature.
liftM :: Monad m => (a -> r) -> (m a1 -> m r)
What would work is if you could define a function liftLast :: Monad m => (a0 -> a1 -> ... -> aN -> r) -> (a0 -> a1 -> ... -> aN -> m r)
then
nary' f = runIdentity . nary (liftLast f)
-- ryan
I don't see a way to implement liftLast or nary for functions like (a -> b -> ... -> r) where r is not of the form (m s). Of course one can use the Identity Monad for m, but in either case you have to modify functions like (Int -> Int) to something like (Int -> m Int) for a fixed type m (e.g. Identity). -- philipp n. -- View this message in context: http://www.nabble.com/distinguish-functions-from-non-functions-in-a-class-in... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Philipp N. wrote:
i'm trying to wrap functions (a -> b -> ... -> z) of any arity to functions of type ([String] -> y), where list of strings replaces the typed arguments.
one attempt looks like this (here written with type families, you can replace it by functional dependencies or what ever):
type family Res x type instance Res x = x type instance Res (x->y) = Res y
class Nary x where nary :: x -> [String] -> Res x
instance Nary x where nary x [] = x
instance Nary (x->y) where nary f (x:xs) = nary (f $ read x) xs
i hope you can get the idea. the problem is, that you cannot distinguish type (x->y) from z, so these instances are overlapping.
Exactly. What you want to do is most likely impossible, which I think is due to polymorphism. What type should the expressions nary id nary ($) have? Nary only works when the result is a monotype, which means that you would have to add every concrete monotype as base case instance Nary Int where nary x [] = x instance Nary Char where nary x [] = x instance Nary a => Nary [a] where nary x [] = x ... etc. Regards, apfelmus
participants (5)
-
apfelmus
-
Brandon S. Allbery KF8NH
-
Dan Weston
-
Philipp N.
-
Ryan Ingram