Skip to content

Instantly share code, notes, and snippets.

@evincarofautumn
Created June 10, 2017 19:09
Show Gist options
  • Save evincarofautumn/38291d4b3651ea86204267f012efe18a to your computer and use it in GitHub Desktop.
Save evincarofautumn/38291d4b3651ea86204267f012efe18a to your computer and use it in GitHub Desktop.
Constrained monads with multi-parameter typeclasses
{-# LANGUAGE FlexibleContexts, FlexibleInstances, MultiParamTypeClasses #-}
import Data.Set (Set)
import qualified Data.Set as Set
class Unit m a where
unit :: a -> m a
class (Unit m a, Unit m b) => Bind m a b where
bind :: m a -> (a -> m b) -> m b
instance Unit [] a where
unit = (:[])
instance Bind [] a b where
bind m k = concatMap k m
instance Unit Set a where
unit = Set.singleton
instance Ord b => Bind Set a b where
bind m k = Set.fold (Set.union . k) Set.empty m
{-
[1, 2, 3] `bind` \a ->
[1, 2, 3] `bind` \b ->
unit (a * b)
==
[1, 2, 3, 2, 4, 6, 3, 6, 9]
Set.fromList [1, 2, 3] `bind` \a ->
Set.fromList [1, 2, 3] `bind` \b ->
unit (a * b)
==
Set.fromList [1, 2, 3, 4, 6, 9]
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment