Skip to content

Instantly share code, notes, and snippets.

View monadplus's full-sized avatar

Arnau Abella monadplus

View GitHub Profile
@monadplus
monadplus / Measure.hs
Created August 10, 2022 17:26
Haskell: be careful when measuring elapsed time
-- | >>> measure (return $ sum [1..100000000])
-- (5000000050000000,1.892e-6)
measure :: IO a -> IO (a, Double)
measure io = do
start <- getMonotonicTimeNSec
a <- io
end <- getMonotonicTimeNSec
return (a, fromIntegral (end - start) / 1_000_000_000)
-- | >>> measure (return $ sum [1..100000000])
@monadplus
monadplus / prometheus.md
Created August 10, 2022 16:02
Prometheus: docker-compose & Haskell example

Example of prometheus-haskell

  • docker-compose.yaml:
version: '3'

services:
  prometheus:
 image: prom/prometheus:v2.30.3
@monadplus
monadplus / Main.dump-simpl.md
Created August 1, 2022 14:11
Haskell: tail recursion affects performance?

ghc -O2 -ddump-simpl -ddump-to-file Main.hs:


==================== Tidy Core ====================
2022-08-01 14:09:19.73363688 UTC

Result size of Tidy Core
  = {terms: 178, types: 217, coercions: 9, joins: 0/0}
@monadplus
monadplus / AtLeastOneMaybe.md
Last active July 5, 2022 10:16
Haskell: At least one maybe field

Suppose we have:

data MyType  = MyType
  { myTypeA :: Maybe A 
  , myTypeB :: Maybe B
  }

How do we guarantee that at least one field is non empty?

@monadplus
monadplus / pointfree.hs
Created July 2, 2022 06:44
Point-Free or Die: Tacit Programming in Haskell and Beyond
{- Point-Free or Die: Tacit Programming in Haskell and Beyond
https://www.youtube.com/watch?v=seVSlKazsNk
g . f = (.) g f x
= \x -> g (f x)
= \x -> g $ f x
= \x -> g . f $ x
= g . f
@monadplus
monadplus / coerce.md
Last active July 1, 2022 11:21
Hasell: coerce

Will they produce the same CORE? With -O2 they do.

newtype A a = MkA { unA :: a }
  deriving newtype Show

data B = B [A String]
  deriving stock Show

foo :: [String] -> B
@monadplus
monadplus / InferenceRule.md
Last active June 30, 2022 19:17
Haskell: class constraint new inference rule

Given the following type families:

type family Elem a as where
  ...

type family NotElem a as where
  ...
@monadplus
monadplus / Sprintf.hs
Last active June 30, 2022 21:05
Haskell: type-safe sprintf
-- Source: Fun with Type Functions
data L
data V a
data f1 :<>: f2
type Parser a = String -> [(a, String)]
type Printer a = a -> String
data F f where
@monadplus
monadplus / Main.hs
Created June 15, 2022 14:05
Haskell: QuantifiedConstraints
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
@monadplus
monadplus / Render.hs
Last active June 7, 2022 20:50
Haskell: type constructor name as symbol
-- | Type constructor name
type TyConsName :: (Type -> Type) -> Symbol
type family TyConsName rep where
TyConsName (D1 (MetaData tyConName _ _ _) _) = tyConName
-- | 'KnownSymbol s' for the 'TyConsName' of 'a'
type Render :: Type -> Constraint
type Render a = KnownSymbol (TyConsName (Rep a))
-- | Given a 'Generic a', returns the name of its type constructor.