Skip to content

Instantly share code, notes, and snippets.

DSl'и и как писать большие программы на PureScript'е

Вступление

Приветы! Меня зовут Максим Зималиев, я работаю в SlamData и уже почти два с половиной года пилю в продакшн код на PureScript'е. Как и большинство пришедших в прекрасный мир ФП, я начинал со всяких там джаваскриптов, пхп и шарпов. Соответственно, у меня есть бывшие коллеги и друзья, которые по-прежнему работают на императивных языках, используют GoF, DDD и тому подобное.

Ну так вот, пойдешь такой пиво пить, и внезапно "Слушай, а как у вас в PureScript'е, например ORM запилить, объектов же нет?" Или: "Это здорово всё, но вот я домены описываю вот так вот, у них там поведение есть, а как это PureScript'е сделать?"

@vyorkin
vyorkin / Fix.hs
Created January 6, 2018 19:06 — forked from xgrommx/Fix.hs
Fix
{-# LANGUAGE RankNTypes, ScopedTypeVariables, DeriveTraversable, PatternSynonyms, UndecidableInstances, FlexibleInstances, ViewPatterns, InstanceSigs #-}
module Fix where
import Control.Monad (ap, join, (<=<))
import Control.Applicative (empty, Alternative, (<|>))
import Control.Arrow
import Data.Functor.Compose
-- Free f a = Mu x. a + f x
@vyorkin
vyorkin / Json.purs
Created January 7, 2018 22:46 — forked from i-am-tom/Json.purs
Parsing, Generating, and Diffing JSON in PureScript
module Main where
-- | JSON is an incredibly simple format. Even its lists are untyped.
-- | As with all languages, functional programming encourages us to
-- | make a domain-specific language (or DSL) to capture the "ideas"
-- | of the language, which we can then use to talk about its content.
-- | In this little snippet, we'll build a JSON DSL, transform it into
-- | a recursive structure, and then use that result to generate some
@vyorkin
vyorkin / ZipDisjointRecord.purs
Created April 22, 2018 15:01 — forked from i-am-tom/ZipDisjointRecord.purs
Zipping records with mismatched keys.
module Main (main, zip, zipRecord, class ZipRowList) where
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Record (get, insert)
import Data.Symbol (class IsSymbol, SProxy(..))
import Data.These (These(..))
import Global.Unsafe (unsafeStringify)
import Prelude (Unit, discard)
import Type.Row
@vyorkin
vyorkin / Main.purs
Created April 22, 2018 15:01 — forked from coot/Main.purs
PureScript: pick subrecords from a record.
module Main where
import Prelude
import Data.Foldable (fold, elem)
import TryPureScript
import Type.Row (class ListToRow, class RowToList, Cons, Nil, kind RowList)
import Type.Proxy (Proxy(..))
import Type.Data.Symbol (class IsSymbol, reflectSymbol)
import Data.Array (cons)
import Data.Monoid (mempty)
class SemigroupJoinRecord rl (row ∷ # Type) where
appendRecordsImpl :: RLProxy rl → Record row -> Record row -> Record row
instance semigroupJoinRecordCons ∷ (Semigroup ty, RowCons name ty row' row, SemigroupJoinRecord tail row, IsSymbol name) ⇒ SemigroupJoinRecord (Cons name ty tail) row where
appendRecordsImpl _ r1 r2 =
let
_name = (SProxy ∷ SProxy name)
v1 = get _name r1
@vyorkin
vyorkin / DiffRecords.purs
Created April 22, 2018 15:02 — forked from anilanar/DiffRecords.purs
lodash.without in purescript using RowToList
{-
This is just adventuring with RowToList.
Naive approach, not stack safe, probably too slow.
-}
module DiffRecords
where
import Data.Record (get, insert)
import Data.Symbol (class IsSymbol, SProxy(..))
@vyorkin
vyorkin / extract-fieldnames.purs
Created April 22, 2018 15:02 — forked from justinwoo/extract-fieldnames.purs
extract field names from rows using rowtolist
module Main where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, logShow)
import Data.Symbol (class IsSymbol, SProxy(..), reflectSymbol)
import Type.Proxy (Proxy(..))
import Type.Row (class ListToRow, class RowToList, Cons, Nil, kind RowList)
@vyorkin
vyorkin / ZipRecord.purs
Created April 22, 2018 15:02 — forked from i-am-tom/ZipRecord.purs
ZipRecord for PureScript. More notes from RowToList studies.
module Main (main, zip, zipRecord, class ZipRowList) where
-- | After Tuesday's experiments, let's move onto a slightly more
-- | interesting example. Last time, I confess, I cheated a bit to
-- | avoid getting too deep into RowToList stuff. Today, I'm not
-- | going to cheat, and get riiiight into it. When we're thirty lines
-- | in, don't say you weren't warned!
import Prelude (($), discard, Unit)
import Control.Monad.Eff (Eff)