I’ve been continuing to work through the exercises in The Little Schemer and came across a problem which needed me to write a function to take a mixed list of Integers and Strings and filter out the Integers.
As I mentioned in my previous post I’ve been doing the exercises in Haskell but I thought I might struggle with that approach here because Haskell collections are homogeneous i.e. all the elements need to be of the same type.
Using Dynamic we can define a function to strip out the numbers like this:
import Data.Dynamic import Data.Maybe noNums :: [Dynamic] -> [Dynamic] noNums lat = cond [(null lat, ), (isNumber (head lat), noNums (tail lat)), (otherwise, head lat : noNums (tail lat))] justInt :: Dynamic -> Maybe Int justInt dyn = fromDynamic dyn :: Maybe Int isNumber :: Dynamic -> Bool isNumber x = isJust $ justInt x
We can then call the function like this:
> map toString $ noNums [toDyn (5 :: Int), toDyn "pears", toDyn (6 :: Int), toDyn "prunes", toDyn (9 :: Int), toDyn "dates"] [Just "pears",Just "prunes",Just "dates"]
toString :: Dynamic -> Maybe String toString dyn = fromDynamic dyn
fromDynamic eventually makes a call to unSafeCoerce#:
The function unsafeCoerce# allows you to side-step the typechecker entirely. That is, it allows you to coerce any type into any other type. If you use this function, you had better get it right, otherwise segmentation faults await. It is generally used when you want to write a program that you know is well-typed, but where Haskell’s type system is not expressive enough to prove that it is well typed.
I wanted to try and make the ‘isNumber’ function handle any numeric type rather than just Ints but I haven’t quite worked out how to do that.
Obviously I’m only using Dynamic here because the exercise requires it but I’m not sure what real life situation would require its use.
If anyone has used it before or knows a use case I’d be interested to know what it is!