Different return type?

Hi, Possibly a silly question but is it possible to have a function that has a different return type based on it's first argument? For instance data Person = Person { name :: String, ... } data Business = Business { business_number :: Int, ...} key person = name person key business = business_number business Thanks -John

Am Montag, 19. Januar 2009 02:44 schrieb John Ky:
Hi,
Possibly a silly question but is it possible to have a function that has a different return type based on it's first argument?
For instance
data Person = Person { name :: String, ... } data Business = Business { business_number :: Int, ...}
key person = name person key business = business_number business
Thanks
-John
Well, you could use {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances #-} module Key where data Person = Person { name :: String } data Business = Business { business_number :: Int} class Key a b | a -> b where key :: a -> b instance Key Person String where key = name instance Key Business Int where key = business_number or with type families: {-# LANGUAGE TypeFamilies #-} class Key2 a where type Res a key2 :: a -> Res a instance Key2 Person where type Res Person = String key2 = name instance Key2 Business where type Res Business = Int key2 = business_number but apart from that and parametrically polymorphic functions (of type a -> [a] or the like), I don't think it's possible, it would need dependent types. HTH, Daniel

Hi Daniel,
When would I use either? What are the trade-offs?
Thanks
-John
On Mon, Jan 19, 2009 at 1:13 PM, Daniel Fischer
Am Montag, 19. Januar 2009 02:44 schrieb John Ky:
Hi,
Possibly a silly question but is it possible to have a function that has a different return type based on it's first argument?
For instance
data Person = Person { name :: String, ... } data Business = Business { business_number :: Int, ...}
key person = name person key business = business_number business
Thanks
-John
Well, you could use
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances #-} module Key where
data Person = Person { name :: String } data Business = Business { business_number :: Int}
class Key a b | a -> b where key :: a -> b
instance Key Person String where key = name
instance Key Business Int where key = business_number
or with type families: {-# LANGUAGE TypeFamilies #-} class Key2 a where type Res a key2 :: a -> Res a
instance Key2 Person where type Res Person = String key2 = name
instance Key2 Business where type Res Business = Int key2 = business_number
but apart from that and parametrically polymorphic functions (of type a -> [a] or the like), I don't think it's possible, it would need dependent types.
HTH, Daniel

Hello! I wouldn't use either. It seems like it complicates things quite a lot and it looks like this could be solved more simply by setting up the data types or organizing functions differently. Is there a specific problem that you're solving or are you just curious about different return types based on input types? Cheerio!

"John Ky"
Hi,
Possibly a silly question but is it possible to have a function that has a different return type based on it's first argument?
Are you sure that's what you really want?
For instance
data Person = Person { name :: String, ... } data Business = Business { business_number :: Int, ...}
data Entity = Person {...} | Business {...}
key person = name person key business = business_number business
data Key = PersonKey String | BusinessKey Int It seems likely that you are at least sometimes going to want to pass the result of key to some other function. ...? -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2008-04-26)

John Ky
data Person = Person { name :: String, ... } data Business = Business { business_number :: Int, ...}
key person = name person key business = business_number business
Let's make this concrete: data Person = Person { name :: String, age :: Integer } data Business = Business { business_number :: Int, revenue :: Double } key person = name person key business = business_number business Even without dependent types, you can do the following (but of course, you lose some syntactic sugar for records): data Individual k v = Individual { key :: k, value :: v } type Person = Individual String Integer type Business = Individual Int Double name :: Person -> String name = key age :: Person -> Integer age = value business_number :: Business -> Int business_number = key revenue :: Business -> Double revenue = value -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig May all beings be well and happy!~
participants (5)
-
Chung-chieh Shan
-
Daniel Fischer
-
John Ky
-
Jon Fairbairn
-
Miran Lipovaca