This commit is contained in:
Correl Roush 2022-03-16 19:56:10 -04:00
parent 94dee13329
commit e8ab186b48
6 changed files with 109 additions and 6 deletions

View file

@ -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

View file

@ -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

View file

@ -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=

View file

@ -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

View file

@ -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

View file

@ -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]].