Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Haskell, how to do a case statement on Dynamic TypeRef

I tried the following:

intType =  typeOf (5::Int)
stringType = typeOf "s"

dynFunc :: Dynamic -> IO ()
dynFunc d =
  case dynTypeRep d of
    stringType -> polyFunc ((fromDyn d "") :: String)
    intType -> polyFunc ((fromDyn d 0) :: Int)
    _      -> error "Could not coerce dynamic value"

But it warns of overlapping pattern matches and doesn't work right. It always goes to first pattern instead of the correct one.

like image 273
mentics Avatar asked Apr 10 '26 03:04

mentics


1 Answers

The left hand sides of the -> in a case expression are patterns, not expressions. The pattern stringType will match anything and bind the local name stringType to it. It will not compare for equality.

The compiler is telling you that your patterns intType and _ will never be reached; since the stringType pattern comes first and matches anything, its right hand side will always be chosen.

As Claudiu suggested, you'll want to use guards instead. Something like this should do the trick:

dynFunc d | rep == stringType = ...
          | rep == intType    = ...
          | otherwise         = error ...
          where rep = dynTypeRep d

If you have many possibilities, you might want to consider making a list and using the lookup function.

like image 132
hammar Avatar answered Apr 12 '26 22:04

hammar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!