I'm trying to write a function whose return type depends on the value of one of its inputs.
In Idris, it is straightforward:
module Dependent
IntOrChar : Bool -> Type
IntOrChar True = Int
IntOrChar False = Char
fun : (x : Bool) -> IntOrChar x
fun True = 10
fun False = 'a'
With those definitions:
λΠ> fun True
10 : Int
λΠ> fun False
'a' : Char
My question is: can I do a similar thing in a simple manner in Haskell?
I suppose I could use something like singletons, but I don't know how to use them properly.
This works:
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE TypeFamilies #-}
module Main where
import Data.Singletons.Prelude
type family IntOrChar (x :: Bool) where
  IntOrChar True = Int
  IntOrChar False = Char
fun :: SBool b -> IntOrChar b
fun b = case b of
          STrue -> 10
          SFalse -> 'a'
...
λ fun STrue
10
λ fun SFalse
'a'
But it requires me to use SBools instead of plain Bools. I'd rather use it as fun True.
Is there a way to make the equivalent of fun : (x : Bool) -> IntOrChar x in Haskell?