Created
April 13, 2018 16:30
-
-
Save cdepillabout/2f7fe4581a915c6962747b275dddf7c0 to your computer and use it in GitHub Desktop.
Example of how it is possible to override the functions that get called for a typeclass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE AllowAmbiguousTypes #-} | |
{-# LANGUAGE ConstraintKinds #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE RankNTypes #-} | |
{-# LANGUAGE TypeApplications #-} | |
-- | This modules shows how it is possible to override the functions that get | |
-- called for a typeclass. | |
-- | |
-- For instance, the 'foo' function overrides the '(<>)' function for | |
-- 'Semigroup', making it work differently for 'Sum' 'Int'. | |
module Magic2 where | |
import Data.Semigroup (Sum) | |
import Unsafe.Coerce | |
-- | This is a wrapper used in 'doMagic' | |
newtype Magic c r = Magic { unMagic :: c => r } | |
-- | This function is where the magic happens. The first argument is run with | |
-- the second argument passed as the typeclass dictionary. | |
doMagic :: forall c b r. (c => r) -> b -> r | |
doMagic r b = | |
let magic = Magic r :: Magic c r | |
in unsafeCoerce magic b | |
-- | This is a wrapper for the 'Semigroup' typeclass dictionary. | |
data MySemi a = MySemi { app :: a -> a -> a } | |
badMinusSemi :: MySemi (Sum Int) | |
badMinusSemi = MySemi (-) | |
-- This function is a wrapper around 'f' that calls it with a different '(<>)' | |
-- function. | |
-- | |
-- >>> bar | |
-- Sum {getSum = 1} | |
bar :: Sum Int | |
bar = doMagic @(Semigroup (Sum Int)) (f 4 3) badMinusSemi | |
-- | This is a function that we want to run with a different typeclass | |
-- dictionary. | |
f :: forall a. Semigroup a => a -> a -> a | |
f a b = a <> b |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Can be loaded into GHCi like the following: