forked from orion/obsidian
update
This commit is contained in:
parent
3701b1e2f8
commit
d74fc46755
3
fp/.obsidian/appearance.json
vendored
3
fp/.obsidian/appearance.json
vendored
@ -2,5 +2,6 @@
|
||||
"theme": "obsidian",
|
||||
"accentColor": "#745eff",
|
||||
"interfaceFontFamily": "",
|
||||
"baseFontSize": 20
|
||||
"baseFontSize": 22,
|
||||
"nativeMenus": false
|
||||
}
|
2
fp/.obsidian/graph.json
vendored
2
fp/.obsidian/graph.json
vendored
@ -17,6 +17,6 @@
|
||||
"repelStrength": 10,
|
||||
"linkStrength": 1,
|
||||
"linkDistance": 250,
|
||||
"scale": 0.6174207201407237,
|
||||
"scale": 0.36924895020525084,
|
||||
"close": true
|
||||
}
|
53
fp/.obsidian/workspace.json
vendored
53
fp/.obsidian/workspace.json
vendored
@ -4,11 +4,11 @@
|
||||
"type": "split",
|
||||
"children": [
|
||||
{
|
||||
"id": "1ae4bfe7bb551ca1",
|
||||
"id": "eecc282740820263",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "d3a2cb4690ca618a",
|
||||
"id": "6465d16034124b8f",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "graph",
|
||||
@ -65,8 +65,7 @@
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300,
|
||||
"collapsed": true
|
||||
"width": 300
|
||||
},
|
||||
"right": {
|
||||
"id": "75cf567121b661bb",
|
||||
@ -141,12 +140,32 @@
|
||||
"publish:Publish changes...": false
|
||||
}
|
||||
},
|
||||
"active": "d3a2cb4690ca618a",
|
||||
"active": "6465d16034124b8f",
|
||||
"lastOpenFiles": [
|
||||
"Classes/Alternative/Alt.md",
|
||||
"Classes/Alternative/Plus.md",
|
||||
"Monads/Transformers/MaybeT.md",
|
||||
"Monads/Transformers/ExceptT.md",
|
||||
"Monads/Transformers/ReaderT.md",
|
||||
"Monads/Transformers/WriterT.md",
|
||||
"Monads/Transformers/StateT.md",
|
||||
"Monads/Transformers",
|
||||
"Classes/Alternative/Alternative.md",
|
||||
"Classes/Functor/Applicative.md",
|
||||
"Classes/Functor/Apply.md",
|
||||
"Classes/Functor/Functor.md",
|
||||
"Classes/Collapsing",
|
||||
"Classes/Bind",
|
||||
"Classes/Functor",
|
||||
"Classes/Alternative",
|
||||
"Language/Infix Operators/Common Operators/Data.md",
|
||||
"Classes/Traversable.md",
|
||||
"Data/Collections/NonEmptyArray.md",
|
||||
"Data/Collections/NonEmptyList.md",
|
||||
"Data/String.md",
|
||||
"Data/Collections.md",
|
||||
"Data/Collections/HashMap.md",
|
||||
"Data/Product",
|
||||
"Data/Untitled.md",
|
||||
"Data/Sum",
|
||||
"Data/Collections/HashSet.md",
|
||||
"Data/Collections/Set.md",
|
||||
@ -158,27 +177,7 @@
|
||||
"Language/Row Types/Record.md",
|
||||
"Data/Product/Tuple.md",
|
||||
"Language/Row Types",
|
||||
"Data/Sum/Either.md",
|
||||
"Language/Functions.md",
|
||||
"Language/Functions/Defining/Guard Clause.md",
|
||||
"Language/Typeclasses.md",
|
||||
"Language/Type Signature.md",
|
||||
"Class/Monoid.md",
|
||||
"Class/Semigroup.md",
|
||||
"Class/Math/EuclideanRing.md",
|
||||
"Class/Math/Semiring.md",
|
||||
"Class/Math/DivisionRing.md",
|
||||
"Class/Math/Ring.md",
|
||||
"Class/Semiring.md",
|
||||
"Class/Math",
|
||||
"Class/Foldable.md",
|
||||
"Terminology/Purity.md",
|
||||
"Language/Expressions/do notation.md",
|
||||
"Monads/Classes/Stack-safe recursion",
|
||||
"Monads/Classes/Early Return",
|
||||
"Monads/Classes/State",
|
||||
"Monads/Classes/F",
|
||||
"Monads/Classes/Error Handling",
|
||||
"Classes/Math",
|
||||
"Untitled 1.canvas",
|
||||
"Untitled.canvas"
|
||||
]
|
||||
|
@ -1,12 +0,0 @@
|
||||
Generalizes [[Functor]] to functions with 2+ arguments
|
||||
|
||||
```haskell
|
||||
apply ::
|
||||
forall f a b
|
||||
. Apply f
|
||||
=> f (a -> b)
|
||||
-> f a
|
||||
-> f b
|
||||
|
||||
infixl apply as <*>
|
||||
```
|
52
fp/Classes/Alternative/Alt.md
Normal file
52
fp/Classes/Alternative/Alt.md
Normal file
@ -0,0 +1,52 @@
|
||||
Alt is used most often as boolean OR on fallible [[Functor|functors]], but is technically whatever associative operation makes sense for the [[Data Structures|data]] type.
|
||||
|
||||
```haskell
|
||||
class Functor f <= Alt f where
|
||||
alt :: forall a. f a -> f a -> f a
|
||||
```
|
||||
|
||||
### Examples
|
||||
In [[Maybe]], Alt allows chainable defaults:
|
||||
```haskell
|
||||
Just 1 <|> Just 2
|
||||
-- Just 1
|
||||
|
||||
Nothing <|> Just 1
|
||||
-- Just 1
|
||||
|
||||
Nothing <|> Nothing
|
||||
-- Nothing
|
||||
|
||||
Nothing <|> Nothing <|> Just 1
|
||||
-- Just 1
|
||||
```
|
||||
|
||||
In [[Either]], Alt works as a try/catch:
|
||||
```haskell
|
||||
Left "error!" <|> Right "it's ok i recovered"
|
||||
-- Right "it's ok i recovered"
|
||||
|
||||
Right "i succeeded!" <|> Right "backup"
|
||||
-- Right "i succeeded!"
|
||||
|
||||
Right unit <|> Left "uh oh!"
|
||||
-- Right unit
|
||||
|
||||
Left "a" <|> Left "b"
|
||||
-- Left "b"
|
||||
```
|
||||
|
||||
> [!attention]
|
||||
> Note that Alt in Either takes the last `Left` when all are `Left`!
|
||||
|
||||
In [[Array]], Alt is append:
|
||||
```haskell
|
||||
[] <|> [] -- []
|
||||
|
||||
["a"] <|> [] -- ["a"]
|
||||
|
||||
[] <|> ["a"] -- ["a"]
|
||||
|
||||
["a"] <|> ["b"] -- ["a", "b"]
|
||||
["a"] <|> ["b", "c"] -- ["a", "b", "c"]
|
||||
```
|
1
fp/Classes/Alternative/Alternative.md
Normal file
1
fp/Classes/Alternative/Alternative.md
Normal file
@ -0,0 +1 @@
|
||||
Doesn't have any class members, just requires that `f` in `Alternative f` must also be [[Plus]] and [[Alt]].
|
39
fp/Classes/Alternative/Plus.md
Normal file
39
fp/Classes/Alternative/Plus.md
Normal file
@ -0,0 +1,39 @@
|
||||
Extends [[Alt]] with an empty value:
|
||||
|
||||
```haskell
|
||||
class Alt f <= Plus f where
|
||||
empty :: forall a. f a
|
||||
```
|
||||
|
||||
> [!info]
|
||||
> Conceptually, this lives next to [[Applicative|pure]] in my mind; in [[Maybe]] for example `pure` and `empty` are aliases for `Just` and `Nothing`.
|
||||
|
||||
In [[Array]], `empty` is empty array `[]`. In [[Maybe]], `empty` is `Nothing`.
|
||||
|
||||
The most common place you'll see `empty` is when using [[MaybeT]] as an early return:
|
||||
|
||||
```haskell
|
||||
logDebug :: String -> Effect Unit
|
||||
logDebug msg = void $ runMaybeT do
|
||||
env <- MaybeT $ Process.lookupEnv "NODE_ENV"
|
||||
when (env /= "DEVELOPMENT") empty
|
||||
lift $ Console.log msg
|
||||
```
|
||||
|
||||
this is equivalent to:
|
||||
|
||||
```haskell
|
||||
logDebug :: String -> Effect Unit
|
||||
logDebug msg = do
|
||||
menv <- Process.lookupEnv "NODE_ENV"
|
||||
case menv of
|
||||
Just env ->
|
||||
if env == "DEVELOPMENT" then
|
||||
Console.log msg
|
||||
else
|
||||
pure unit
|
||||
Nothing -> pure unit
|
||||
```
|
||||
|
||||
> [!info]
|
||||
> Note that [guard](https://pursuit.purescript.org/packages/purescript-control/docs/Control.Alternative#v:guard) is a shorthand available for `when (..) empty`
|
18
fp/Classes/Functor/Applicative.md
Normal file
18
fp/Classes/Functor/Applicative.md
Normal file
@ -0,0 +1,18 @@
|
||||
Adds the `pure` [[Functions|function]] to [[Apply]], allowing arbitrary values to be wrapped in a [[Functor]].
|
||||
|
||||
```haskell
|
||||
class Apply f <= Applicative f where
|
||||
pure :: forall a. a -> f a
|
||||
```
|
||||
|
||||
### Examples
|
||||
`pure a` in various types:
|
||||
|
||||
type|equivalent to
|
||||
---|---
|
||||
[[Array]]|`[a]`
|
||||
[[List]]|`Cons a`
|
||||
[[Maybe]]|`Just a`
|
||||
[[Either]]|`Right a`
|
||||
[[Effect]]|`() => a`<sup><i>more or less</i></sup>
|
||||
[[Aff]]|`Promise.resolve(a)`<sup><i>more or less</i></sup>
|
79
fp/Classes/Functor/Apply.md
Normal file
79
fp/Classes/Functor/Apply.md
Normal file
@ -0,0 +1,79 @@
|
||||
Generalizes [[Functor#map|map]] to [[Functions|functions]] with 2+ arguments; lifting functions `a -> b -> c` to `f a -> f b -> f c`
|
||||
|
||||
```haskell
|
||||
class Functor f <= Apply f where
|
||||
apply :: forall a b. f (a -> b) -> f a -> f b
|
||||
|
||||
infixl apply as <*>
|
||||
```
|
||||
|
||||
> [!tip]
|
||||
> Apply often replaces the pattern of "building towards a final result"
|
||||
>
|
||||
> Consider a function that [[Tuple|tuple]]s together its arguments
|
||||
> ```haskell
|
||||
> mk3Tuple a b c = a /\ b /\ c
|
||||
> ```
|
||||
>
|
||||
> A common situation is wanting to build something like this 3-tuple from some components that are trapped in a context like [[Maybe]] or [[Either]], and we want to say "when all these things are ok, build it"; this is exactly what Apply lets us do:
|
||||
>
|
||||
> ```haskell
|
||||
> maybeMk3Tuple :: Maybe a -> Maybe b -> Maybe c -> Maybe (a /\ b /\ c)
|
||||
> maybeMk3Tuple ma mb mc = Just mk3Tuple <*> ma <*> mb <*> mc
|
||||
>
|
||||
> maybeMk3Tuple (Just 1) (Just 2) (Just 3)
|
||||
> -- Just (1 /\ 2 /\ 3)
|
||||
>
|
||||
> maybeMk3Tuple (Just "a") (Just 3) (Nothing)
|
||||
> -- Nothing
|
||||
>
|
||||
> maybeMk3Tuple Nothing Nothing Nothing
|
||||
> -- Nothing
|
||||
> ```
|
||||
|
||||
> [!tip]
|
||||
> Obscure but occasionally usefully, Apply in collections lets us apply multiple functions to each element:
|
||||
> ```haskell
|
||||
> [(_ * 10), (_ * 20)] <*> [1, 2, 3]
|
||||
> -- [10, 20, 20, 40, 30, 60]
|
||||
>
|
||||
> [identity, const ", "] <*> ["a", "b", "c"]
|
||||
> -- ["a", ",", "b", ",", "c", ","]
|
||||
> ```
|
||||
|
||||
### Examples
|
||||
|
||||
lift `(a + b) / c` to [[Maybe]]
|
||||
```haskell
|
||||
f :: Number -> Number -> Number
|
||||
f a b c = (a + b) / c
|
||||
|
||||
mf :: Maybe Number -> Maybe Number -> Maybe Number
|
||||
mf ma mb mc = pure f <*> ma <*> mb <*> mc
|
||||
```
|
||||
|
||||
Build up a `Person` [[Record|record]] from Maybe fields; short-circuiting to `Nothing` if any fields are `Nothing`
|
||||
```haskell
|
||||
type PartialPerson =
|
||||
{ name :: Maybe String
|
||||
, email :: Maybe String
|
||||
, password :: Maybe String
|
||||
}
|
||||
|
||||
type Person =
|
||||
{ name :: String
|
||||
, email :: String
|
||||
, password :: String
|
||||
}
|
||||
|
||||
person :: PartialPerson -> Person
|
||||
person
|
||||
{ name: name'
|
||||
, email: email'
|
||||
, password: password'
|
||||
} =
|
||||
let
|
||||
buildPerson name email password = {name, email, password}
|
||||
in
|
||||
Just buildPerson <*> name' <*> email' <*> password'
|
||||
```
|
@ -1,4 +1,3 @@
|
||||
## What
|
||||
[[Typeclasses|Typeclass]] defining the [[Functions|function]] `map`, [[Infix Operators|operators]] `<$>`, and `<#>`.
|
||||
|
||||
```haskell
|
||||
@ -6,11 +5,21 @@ class Functor f where
|
||||
map :: forall a b. (a -> b) -> f a -> f b
|
||||
```
|
||||
|
||||
## Why
|
||||
Modify the data contained in a [[Data Structures|data structure]]
|
||||
## map
|
||||
For a [[Data Structures|data structure]] containing some data `a`, change the data using some function `a -> b`.
|
||||
|
||||
### Abstracts
|
||||
- For every element in [[Collections|collection]] ...
|
||||
> [!info]
|
||||
> Another way of thinking of map is that it **lifts** a function of `a -> b` to `f a -> f b`:
|
||||
> ```haskell
|
||||
> addTwo :: Int -> Int
|
||||
> addTwo = add 2
|
||||
>
|
||||
> maybeAddTwo :: Maybe Int -> Maybe Int
|
||||
> maybeAddTwo = map addTwo
|
||||
> ```
|
||||
|
||||
Replaces the patterns:
|
||||
- Modify every element in [[Collections|collection]] ...
|
||||
- When [[Maybe|nullable]] value is non-null ...
|
||||
- When _(potentially async)_ [[Effect|IO]] resolves ...
|
||||
|
@ -1,6 +1,7 @@
|
||||
|Operator|Description|Associativity|Precedence|Defined As|
|
||||
|--|--|--|--|--|
|
||||
|`<>`|append|right|5|[`Data.Semigroup.append`](https://pursuit.purescript.org/packages/purescript-prelude/docs/Data.Semigroup#v:(%3C%3E))|
|
||||
|`/\`|Tuple constructor|right|6|[`Data.Tuple.Nested.Tuple`](https://pursuit.purescript.org/packages/purescript-tuples/docs/Data.Tuple.Nested#v:(%2F%5C))|
|
||||
|`<$>`|map|||
|
||||
|`<#>`|flipped map|||
|
||||
|`<*>`|apply (map using function of 2+ arguments)|||
|
||||
|
0
fp/Monads/Transformers/ExceptT.md
Normal file
0
fp/Monads/Transformers/ExceptT.md
Normal file
0
fp/Monads/Transformers/MaybeT.md
Normal file
0
fp/Monads/Transformers/MaybeT.md
Normal file
0
fp/Monads/Transformers/ReaderT.md
Normal file
0
fp/Monads/Transformers/ReaderT.md
Normal file
0
fp/Monads/Transformers/StateT.md
Normal file
0
fp/Monads/Transformers/StateT.md
Normal file
0
fp/Monads/Transformers/WriterT.md
Normal file
0
fp/Monads/Transformers/WriterT.md
Normal file
Loading…
Reference in New Issue
Block a user