Skip to content

Instantly share code, notes, and snippets.

@jaspervdj
Created October 14, 2019 18:05
Show Gist options
  • Save jaspervdj/7e34a72e09d49d6e06c318e071b98273 to your computer and use it in GitHub Desktop.
Save jaspervdj/7e34a72e09d49d6e06c318e071b98273 to your computer and use it in GitHub Desktop.
Specializing "Handle" functions
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
data Handle = Handle
generic1 :: Handle -> Char -> Bool -> IO ()
generic1 = undefined
generic2 :: Handle -> String -> Char -> Bool -> IO ()
generic2 = undefined
--------------------------------------------------------------------------------
-- Method 1: the "haskell" way
specialized1 :: Handle -> Bool -> IO ()
specialized1 = generic1 .< 'a'
specialized2 :: Handle -> Bool -> IO ()
specialized2 = generic2 .< "Hello" .< 'b'
(.<) :: (a -> b -> c) -> b -> (a -> c)
(.<) = flip
--------------------------------------------------------------------------------
-- Method 2: the "I promise to always put a top level signature on it" way
specialized1' :: Handle -> Bool -> IO ()
specialized1' = specialize generic1 'a'
specialized2' :: Handle -> Bool -> IO ()
specialized2' = specialize generic2 "Hello" 'b'
class Specialize f g where
specialize :: f -> g
instance Specialize (a -> b) (a -> b) where
specialize = id
instance Specialize (a -> c) f => Specialize (a -> b -> c) (b -> f) where
specialize f = \b -> specialize (\a -> f a b)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment