Last active
July 28, 2021 03:00
-
-
Save mgsloan/d1acbabd30d068ef7d3c13f49eb40894 to your computer and use it in GitHub Desktop.
Simplified function composition with variadic 2nd function (simplified but only works well for monomorphic arguments)
This file contains 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 FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE MultiParamTypeClasses #-} | |
-- https://gist.github.com/mgsloan/7100f55c6ec12be8776a1a1c347cf963 | |
-- for a more complex version with better type inference. | |
-- | |
-- It was initially surprising to me that this one doesn't need the | |
-- "closed type family" trick to direct which instance is used. On | |
-- further thought, | |
-- f is a function (a -> r) mapping the result type. | |
-- g is the input function type, before the result is mapped. | |
-- h is the output function type, after the result is mapped. | |
class MapResult f g h where | |
mapResult :: f -> g -> h | |
-- Handles the base case where g has been supplied all its arguments, | |
-- and so is a value of type r that can be passed to f. | |
instance MapResult (a -> r) a r where | |
mapResult f x = f x | |
-- Handles the recursive case where g and h are functions. | |
instance MapResult f g h => MapResult f (x -> g) (x -> h) where | |
mapResult f g = \x -> mapResult f (g x) | |
-- A few monomorphic functions to use below | |
intToString = show :: Int -> String | |
addInts = (+) :: Int -> Int -> Int | |
add3Ints = (\x y z -> x + y + z) :: Int -> Int -> Int -> Int | |
showAddNumbers :: Int -> Int -> String | |
showAddNumbers = mapResult intToString addInts | |
showAdd3Numbers :: Int -> Int -> Int -> String | |
showAdd3Numbers = mapResult intToString add3Ints | |
main :: IO () | |
main = do | |
putStrLn (showAddNumbers 24 13) | |
putStrLn (showAdd3Numbers 24 13 36) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment