Skip to content

Instantly share code, notes, and snippets.

@danidiaz
Last active December 3, 2017 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danidiaz/5fb8ac9ecf40875617cba503214dd3c2 to your computer and use it in GitHub Desktop.
Save danidiaz/5fb8ac9ecf40875617cba503214dd3c2 to your computer and use it in GitHub Desktop.
injection experiment
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies,
GeneralizedNewtypeDeriving, DeriveGeneric,
ConstraintKinds, FunctionalDependencies, UndecidableSuperClasses, RankNTypes, TypeApplications, ScopedTypeVariables,
DefaultSignatures, FlexibleInstances #-}
module Main where
import Data.Proxy
import Control.Monad.IO.Class
import Control.Monad.State.Strict
import GHC.Generics
import Control.Newtype
import Lens.Micro
import Lens.Micro.Mtl
class Monad n => DBState n s where
save' :: Int -> StateT s n ()
load' :: StateT s n Int
class DB m where
save :: Int -> m ()
default save :: forall n e e'.(Newtype (m ()), O (m ()) ~ StateT e n (),Has (DBState n) e e') => Int -> m ()
save i = pack $ zoom (getLens (Proxy @(DBState n))) $ save' i
load :: m Int
default load :: forall n e e'.(Newtype (m Int), O (m Int) ~ StateT e n Int,Has (DBState n) e e') => m Int
load = pack $ zoom (getLens (Proxy @(DBState n))) $ load'
--
data DummyDBState = DummyDBState
instance MonadIO m => DBState m DummyDBState where
save' = undefined
load' = undefined
--
--class Has a b where
-- getLens :: Lens' b a
-- The component is determined by the constraint and the global record type.
class c b => Has c a b | c a -> b where
getLens :: Proxy c -> Lens' a b
--
instance MonadIO n => Has (DBState n) ((),DummyDBState) DummyDBState where
getLens _ = _2
-- The idea is being able to standalone derive DB for newtypes over StateT,
-- when a component of the state has a suitable DBState instance.
newtype Foo r = Foo { getFoo :: StateT ((),DummyDBState) IO r } deriving (Functor,Applicative,Monad,Generic)
instance Newtype (Foo r)
instance DB Foo
main :: IO ()
main = putStrLn "Hello, Haskell!"
-- Initial injecty.cabal generated by cabal init. For further
-- documentation, see http://haskell.org/cabal/users-guide/
name: injecty
version: 0.1.0.0
-- synopsis:
-- description:
license: BSD3
license-file: LICENSE
author: daniel
maintainer: daniel@bogusemailserver.com
-- copyright:
-- category:
build-type: Simple
extra-source-files: ChangeLog.md
cabal-version: >=1.10
executable injecty
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base >=4.10 && <4.11,
transformers >= 0.5.5.0,
mtl >= 2.2.1,
microlens >= 0.4.8.1,
microlens-mtl >= 0.1.11.0,
newtype-generics >= 0.5.1
-- hs-source-dirs:
default-language: Haskell2010
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment