diff --git a/20220310115927-monad.org b/20220310115927-monad.org index 8f749d8..b12466a 100644 --- a/20220310115927-monad.org +++ b/20220310115927-monad.org @@ -6,3 +6,20 @@ #+begin_quote A monad is just a [[id:434ee61c-4461-424f-8dba-5c86ddb06c3c][monoid]] in the category of endofunctors. #+end_quote + +In [[id:9e68d422-cced-4177-96d1-90f777b9a493][Software Development]], this refers to an [[id:10eb4672-19ab-4275-a110-5446c96e7e24][Applicative Functor]] that provides a +method for applyling a function taking a bare value and returning a wrapped +value to a value already wrapped in that same type. + +In [[id:9ac78677-2602-4a06-af0a-4ed82e98a9b6][Haskell]], the function to do this is called *bind*, and is available as the +infix operator ~>>=~. This method is useful for sequentially applying functions +which generate values wrapped in a Monad, abstracting away logic between each +sequential application. This behavior leads some people to refer to Monads as +"programmable semicolons", referring to imperative, C-like languages in which +each line of code is terminated with a semicolon and executed in sequence. +Haskell's "do notation" provides syntactic sugar for codifying such sequences. + +#+caption: Bind function in Haskell +#+begin_src haskell :exports code + (>>=) :: Monad m => m a -> (a -> m b) -> m b +#+end_src diff --git a/20220312165500-semigroup.org b/20220312165500-semigroup.org index 922c4d0..3cdd0b7 100644 --- a/20220312165500-semigroup.org +++ b/20220312165500-semigroup.org @@ -3,5 +3,20 @@ :END: #+title: Semigroup -A category of types such that two values of the type can be combined -associatively to create a new value of the same type. +In [[id:9e68d422-cced-4177-96d1-90f777b9a493][Software Development]], a Semigroup is a category of types such that two values +of the type can be combined associatively to create a new value of the same +type. + +In [[id:9ac78677-2602-4a06-af0a-4ed82e98a9b6][Haskell]], the function to combine two semigroup values is =mappend=, also +available as the infix operator =<>=. =mconcat= is also provided for combining a +list of semigroup values into a single new value. The =mappend= and =mconcat= +functions are part of the [[id:434ee61c-4461-424f-8dba-5c86ddb06c3c][Monoid]] type class in Haskell, as it was introduced to +the language prior to Semigroup, and were given those names as the most common +[[id:434ee61c-4461-424f-8dba-5c86ddb06c3c][Monoid]] is a list. + +#+caption: Semigroup functions in Haskell +#+begin_src haskell :exports code + (<>) :: Semigroup a => a -> a -> a + mappend :: Monoid a => a -> a -> a + mconcat :: Monoid a => [a] -> a +#+end_src diff --git a/20220312165629-monoid.org b/20220312165629-monoid.org index 6779822..db1b236 100644 --- a/20220312165629-monoid.org +++ b/20220312165629-monoid.org @@ -5,7 +5,18 @@ A [[id:b22a1c70-02a7-49ce-b5e7-407f1064cd0c][Semigroup]] with an identity value. +In [[id:9ac78677-2602-4a06-af0a-4ed82e98a9b6][Haskell]], the function representing the identity value for a given Monoid is +=mempty=. + +#+caption: =mempty= in Haskell +#+begin_src haskell :exports code + mempty :: Monoid a => a +#+end_src + * Examples -- List :: Combined with =append=, identity value is the empty list (=[]=) -- Number Addition :: Combined with =+=, identity value is =0= -- Number Multiplication :: Combined with =*=, identity value is =1= +** List +Combined with =append=, identity value is the empty list (=[]=) +** Number Addition +Combined with =+=, identity value is =0= +** Number Multiplication +Combined with =*=, identity value is =1= diff --git a/20220316184243-functor.org b/20220316184243-functor.org new file mode 100644 index 0000000..a789d62 --- /dev/null +++ b/20220316184243-functor.org @@ -0,0 +1,25 @@ +:PROPERTIES: +:ID: 7a19b34d-c4bb-462b-8fae-581bf06dfdc4 +:END: +#+title: Functor + +In [[id:9e68d422-cced-4177-96d1-90f777b9a493][Software Development]], this refers to a parameterized data type that wraps a +value in a context and provides a method for applying a function to the wrapped +value, independent of the container type. + +In [[id:9ac78677-2602-4a06-af0a-4ed82e98a9b6][Haskell]], the function for applying a function to a value in a functor is +=fmap=, also available as the infix operator =<$>=. + +#+caption: =fmap= in Haskell +#+begin_src haskell :exports code + fmap :: Functor f => (a -> b) -> f a -> f b +#+end_src + +* Examples +** Maybe +#+caption: Implementation of Functor for Maybe in Haskell +#+begin_src haskell :exports code + instance Functor Maybe where + fmap func (Just n) = Just (func n) + fmap func Nothing = Nothing +#+end_src diff --git a/20220316185946-applicative.org b/20220316185946-applicative.org new file mode 100644 index 0000000..e700d9e --- /dev/null +++ b/20220316185946-applicative.org @@ -0,0 +1,35 @@ +:PROPERTIES: +:ID: 10eb4672-19ab-4275-a110-5446c96e7e24 +:END: +#+title: Applicative + +In [[id:9e68d422-cced-4177-96d1-90f777b9a493][Software Development]], this refers to a [[id:7a19b34d-c4bb-462b-8fae-581bf06dfdc4][Functor]] that provides a method for +applying a function wrapped in such a type to a value wrapped in the same type. + +In [[id:9ac78677-2602-4a06-af0a-4ed82e98a9b6][Haskell]], the function for applying a wrapped function to a value wrapped in +the same type is available as the infix operator =<*>=, and facilitates the +application of a function taking an arbitrary number of arguments over multiple +wrapped values. An applicative must also implement the =pure= function, which +takes a single argument and returns it wrapped. + +#+caption: Applicative functions in Haskell +#+begin_src haskell :exports code + pure :: Applicative f => a -> f a + (<*>) :: Applicative f => f (a -> b) -> f a -> f b +#+end_src + +In the following example, =fmap= (=<$>=) first applies the =add= function to the +value =Just 1=, resulting in a function of the type =Just (Int -> Int)=. The +applicative infix operator (=<*>=) then applies that function to the remaining +value =Just 2=, resulting in =Just 3=. + +#+caption: Applying a function over multiple wrapped values +#+begin_src haskell :cache yes :exports both + add :: Int -> Int -> Int + add x y = x + y + + add <$> Just 1 <*> Just 2 +#+end_src + +#+RESULTS[10751e7c3100f27569974ee18b3f34498166dfc5]: +: Prelude> Just 3 diff --git a/railway_oriented_programming_f_for_fun_and_profit.org b/railway_oriented_programming_f_for_fun_and_profit.org index 4d471ec..d8edd27 100644 --- a/railway_oriented_programming_f_for_fun_and_profit.org +++ b/railway_oriented_programming_f_for_fun_and_profit.org @@ -5,4 +5,4 @@ #+title: Railway Oriented Programming | F# for fun and profit A talk on [[id:1a74e6c8-023d-4a04-aae7-74d4428f6de5][Software Architecture]] by Scott Wlaschin on cleanly pipelining -functions with success and failure cases using monadic binding. +functions with success and failure cases using [[id:8ee5037f-0673-4968-9ec4-184bf31dd72d][monadic binding]].