Is there a way to make haskell type this expression?
ls = [4, 3.2, True, "home"]
It's a challenge a friend gived to me, but no ideas come around, also didn't tell me if that is possible, so maybe I'm wasting precious time.
As joke, you can do like this:
{-# LANGUAGE OverloadedStrings #-}
import Data.String
instance Num Bool where
fromInteger 0 = False
fromInteger _ = True
instance Fractional Bool where
fromRational 0 = False
fromRational _ = True
instance IsString Bool where
fromString "" = False
fromString _ = True
ls = [4, 3.2, True, "home"]
But this doesn't have sense.
If the form of the expression is not fundamental, then as wrote in the comments, you can use the ExistentialType. But there are many variants to do that. From use Data.Dynamic to custom existential type.
For example, with Data.Dynamic:
import Data.Dynamic
ls = [toDyn (4 :: Int), toDyn (3.2 :: Double), toDyn True, toDyn "hello"]
With custom type:
{-# LANGUAGE ExistentialQuantification #-}
data Any = forall a. {- here can be restrictions on `a` => -} Any a
ls :: [Any]
ls = [Any (4 :: Int), Any (3.2 :: Double), Any True, Any "home"]
If type set are closed, you can just use ADT:
data Variant = I Int | D Double | B Bool | S String
ls :: [Variant]
ls = [I 4, D 3.2, B true, S "home"]
So, to select right solution need to know more about your issue.
If you just want to print everything in the list, you can use ExistentialQuantification to "hide" the fact that the types are anything beyond having a Show instance (or whatever instance you care about).
Here's a simple example (note the language extension - I know this works in GHC, not sure about other compilers):
{-# LANGUAGE ExistentialQuantification #-}
data Obj = forall a. (Show a) => Obj a
ls :: [Obj]
ls = [Obj 4, Obj 3.2, Obj True, Obj "home"]
printObj :: Obj -> IO ()
printObj (Obj x) = putStrLn (show x)
main = mapM printObj ls
Notice that your list isn't strictly the same as in your question, but Obj can take any type that has a Show instance.
I found something interesting that maybe is close enough, here
data Showable a = forall a. Show a => MkShowable a
pack :: Show a => a -> Showable
pack = MkShowable
hlist :: [Showable]
hlist = [ pack 3
, pack "house"
, pack True
, pack 'y'
, pack (Just Nothing) ]
res = map (\(MkShowable v) -> show v) hlist
printwhich requires aShowinstance.