Bad `id` - Haskell

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.


This sounds like a fun challenge:

For this challenge, you must create a function of type a -> a that is total, correct for almost all types, but if passed a boolean will negate it.


It's actually pretty easy with right tools :big_smile: :

-- [spoiler alert]

badId :: a -> a
badId !a = unsafePerformIO $ getClosureData a <&> \case
  ConstrClosure{ pkg = "ghc-prim", name }
    | name `elem` ["True", "False"] -> unsafeCoerce# not a
  _ -> a

There's so much going on! Mind explaining a bit what "tools" are you using? :smiley:


@Bolt sure - I'm using stuff from GHC.Exts.Heap - specifically, getClosureData, which extracts info about Haskell value
Because in case of constructors, that info includes package and constructor name, I can say if value I'm holding is one of Bool constructors - if it is, I apply not to it, otherwise I keep it as-is


One more thing is that I'm forcing value to make sure that I actually get a constructor and not e.g. thunk that could evaluate to Bool


I liked the solution that used rewrite rules too it seemed clever


Yeah - I went for "reliable" one :big_smile: