Giter Club home page Giter Club logo

extensible's Introduction

logo

Haskell CI Hackage Discord

This package provides extensible poly-kinded records, variants and effects.

Several tutorials can be found at School of Haskell.

Bug reports and contributions are welcome!

extensible's People

Contributors

aiya000 avatar anton-dessiatov avatar at-sushi avatar emilypi avatar forestaa avatar fumieval avatar hexirp avatar hogeyama avatar igrep avatar matsubara0507 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

extensible's Issues

Should catchEff remove an effect?

Maybe I'm wrong, or maybe it's not even possible, but it feels like catchEff should remove an effect, not introduce one.
Here is a similar PureScript library, which, I hope, will serve as an example of what I'm talking about.

[question] Is it faster than MTL?

I read this post and the benchmark says that this is faster than MTL.

Is it true for every condition? Is there any condition where it will be slower? (e.g. deeper stack).

I am trying to learn Free / Freer but hesitate when I heard they are significantly slower than MTL.

Build fails on GHC 8.0.1 on OS X

    /private/var/folders/yx/8tj3yfqs2qvgswckc2_xy70w0000gn/T/stack12408/extensible-0.3.7/src/Data/Extensible/Product.hs:125:1: warning: [-Woverlapping-patterns]
        Pattern match is redundant
        In an equation for ‘hzipWith’: hzipWith _ _ Nil = ...

    /private/var/folders/yx/8tj3yfqs2qvgswckc2_xy70w0000gn/T/stack12408/extensible-0.3.7/src/Data/Extensible/Product.hs:131:1: warning: [-Woverlapping-patterns]
        Pattern match is redundant
        In an equation for ‘hzipWith3’: hzipWith3 _ _ Nil _ = ...

    /private/var/folders/yx/8tj3yfqs2qvgswckc2_xy70w0000gn/T/stack12408/extensible-0.3.7/src/Data/Extensible/Product.hs:132:1: warning: [-Woverlapping-patterns]
        Pattern match is redundant
        In an equation for ‘hzipWith3’: hzipWith3 _ _ _ Nil = ...
    ghc: panic! (the 'impossible' happened)
      (GHC version 8.0.1 for x86_64-apple-darwin):
    	pprIfaceCo

    Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug

Are order-independent records supported?

Whereby the following compiles:

{-# LANGUAGE TemplateHaskell, DataKinds, TypeOperators, FlexibleContexts #-}
{-# OPTIONS_GHC -fno-warn-unticked-promoted-constructors #-}

import Data.Extensible

mkField "x y"
r = emptyRecord

foo = (x @= 1 <: y @= 2 <: r) == (y @= 2 <: x @= 1 <: r)

{-
  main.hs:10:45: error:
      • Couldn't match type ‘'Missing "x"’ with ‘'Expecting (n1 ':> v1)’
          arising from a use of ‘x’
      • In the first argument of ‘(@=)’, namely ‘x’
        In the first argument of ‘(<:)’, namely ‘x @= 1’
        In the second argument of ‘(<:)’, namely ‘x @= 1 <: r’
     |
  10 | foo = (x @= 1 <: y @= 2 <: r) == (y @= 2 <: x @= 1 <: r)
     |                                             ^
-}

build fails with profunctors-4.3.2

Data.Profunctors.Unsafe is Unsafe in those older versions.

Perhaps it would be better to remove all the {-# LANGUAGE Unsafe #-} and have the safety be inferred.

Parentheses required for functions in a Record type definition

I'm not sure this can (or should) be fixed, but let me report for our info.

For example, in ghci, pasting the following snippet raises a type error:

:set -XTypeOperators
:set -XDataKinds
import Data.Extensible
type Foo = Record '["func" >: Int -> Bool]
<interactive>:4:19: error:
    • Expected kind ‘[Assoc k0 *]’,
        but ‘'["func" >: Int -> Bool]’ has kind ‘[*]’
    • In the first argument of ‘Record’, namely
        ‘'["func" >: Int -> Bool]’
      In the type ‘Record '["func" >: Int -> Bool]’
      In the type declaration for ‘Foo’

<interactive>:4:21: error:
    • Expected a type, but
      ‘"func" >: Int’ has kind
      ‘Assoc GHC.Types.Symbol *’
    • In the first argument of ‘Record’, namely
        ‘'["func" >: Int -> Bool]’
      In the type ‘Record '["func" >: Int -> Bool]’
      In the type declaration for ‘Foo’

Because GHC interprets "func" >: Int -> Bool as:

 ("func" >: Int) -> Bool

To avoid the error, we have to wrap the function with parentheses:

type Foo = Record '["func" >: (Int -> Bool)]

Build fails on ghc 7.10.1

  src/Data/Extensible/Internal.hs:108:10:
      Illegal instance declaration for ‘Associate k v xs’
        The liberal coverage condition fails in class ‘Associate’
          for functional dependency: ‘k xs -> v’
        Reason: lhs types ‘k’, ‘xs’ do not jointly determine rhs type ‘v’
      In the instance declaration for ‘Associate k v xs’

Ambiguous type variables when trying to use lens as a setter

The records example gives an example of how to use view from the lens library to access a field which works fine but even using set on the simplest examples fails.

*R Control.Lens Data.Extensible> let (r :: Record '[ "a" >: Int ]) = #a @= 0 <: emptyRecord 
*R Control.Lens Data.Extensible> :t r
r :: Record '["a" >: Int]
*R Control.Lens Data.Extensible> set #a 1 r

<interactive>:30:5: error:
    • Ambiguous type variables ‘t0’, ‘a0’ arising from the overloaded label ‘#a’
      prevents the constraint ‘(GHC.OverloadedLabels.IsLabel
                                  "a"
                                  (ASetter
                                     (Record '["a" >: Int]) t0 a0 Integer))’ from being solved.
        (maybe you haven't applied a function to enough arguments?)
      Relevant bindings include it :: t0 (bound at <interactive>:30:1)
      Probable fix: use a type annotation to specify what ‘t0’, ‘a0’ should be.
      These potential instance exist:
        one instance involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    • In the first argument of ‘set’, namely ‘#a’
      In the expression: set #a 1 r
      In an equation for ‘it’: it = set #a 1 r

[question] Aeson instance

I have take the approach in 'examples/aeson.hs' to declare Record's FromJson/ToJson instance in my own project, but orphan instance always bother me, and newtype wrappers are verbose, is it possible to include Record and Variant's instance for FromJson/ToJson in extensible itself?

Compilation error when building with stack

Hey there! This library looks perfect for what I want to do, only I can't seem to build it. It seems to break on the #define macro in the Dictionary.hs module

Most likely I'm doing something wrong, but I have no idea what. I'm getting a compilation error when adding this library as a dependency and buiding using stack. I've tried this using stack 1.6.1 and 1.6.3, using their lts-9.21 (GHC 8.0.2) and lts-10.2 (GHC 8.2.2), but the effect is the same across all these versions. I'm on OSX. This is the compilation log of the errors.

Any help figuring out what's going on here would be greatly appreciated!

--  While building custom Setup.hs for package extensible-0.4.7 using:
      /Users/jasper/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_2.0.1.0_ghc-8.2.2 --builddir=.stack-work/dist/x86_64-osx/Cabal-2.0.1.0 build --ghc-options " -ddump-hi -ddump-to-file -fdiagnostics-color=always"
    Process exited with code: ExitFailure 1
    Logs have been written to: /Users/jasper/dev/elm-gen/.stack-work/logs/extensible-0.4.7.log

    Configuring extensible-0.4.7...
    Preprocessing library for extensible-0.4.7..
    Building library for extensible-0.4.7..
    [ 1 of 23] Compiling Data.Extensible.Internal ( src/Data/Extensible/Internal.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Internal.o )

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack53745/extensible-0.4.7/src/Data/Extensible/Internal.hs:68:1: warning: [-Wunused-imports]
        The import of ‘Data.Bits’ is redundant
          except perhaps to import instances from ‘Data.Bits’
        To import instances alone, use: import Data.Bits()
       |
    68 | import Data.Bits
       | ^^^^^^^^^^^^^^^^
    [ 2 of 23] Compiling Data.Extensible.HList ( src/Data/Extensible/HList.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/HList.o )
    [ 3 of 23] Compiling Data.Extensible.Internal.Rig ( src/Data/Extensible/Internal/Rig.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Internal/Rig.o )
    [ 4 of 23] Compiling Data.Extensible.Wrapper ( src/Data/Extensible/Wrapper.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Wrapper.o )
    [ 5 of 23] Compiling Data.Extensible.Class ( src/Data/Extensible/Class.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Class.o )
    [ 6 of 23] Compiling Data.Extensible.Sum ( src/Data/Extensible/Sum.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Sum.o )
    [ 7 of 23] Compiling Data.Extensible.Struct ( src/Data/Extensible/Struct.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Struct.o )
    [ 8 of 23] Compiling Data.Extensible.Product ( src/Data/Extensible/Product.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Product.o )
    [ 9 of 23] Compiling Data.Extensible.Plain ( src/Data/Extensible/Plain.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Plain.o )
    [10 of 23] Compiling Data.Extensible.Match ( src/Data/Extensible/Match.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Match.o )
    [11 of 23] Compiling Data.Extensible.Inclusion ( src/Data/Extensible/Inclusion.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Inclusion.o )
    [12 of 23] Compiling Data.Extensible.Nullable ( src/Data/Extensible/Nullable.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Nullable.o )
    [13 of 23] Compiling Data.Extensible.Field ( src/Data/Extensible/Field.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Field.o )
    [14 of 23] Compiling Data.Extensible.Tangle ( src/Data/Extensible/Tangle.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Tangle.o )
    [15 of 23] Compiling Data.Extensible.Record ( src/Data/Extensible/Record.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Record.o )

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack53745/extensible-0.4.7/src/Data/Extensible/Record.hs:63:5: warning: [-Wunused-matches]
        Defined but not used: ‘rec’
       |
    63 |     rec <- newName "rec"
       |     ^^^
    [16 of 23] Compiling Data.Extensible.Label ( src/Data/Extensible/Label.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Label.o )
    [17 of 23] Compiling Data.Extensible.GetOpt ( src/Data/Extensible/GetOpt.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/GetOpt.o )
    [18 of 23] Compiling Data.Extensible.Effect ( src/Data/Extensible/Effect.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Effect.o )
    [19 of 23] Compiling Data.Extensible.TH ( src/Data/Extensible/TH.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/TH.o )
    [20 of 23] Compiling Data.Extensible.Effect.Default ( src/Data/Extensible/Effect/Default.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Effect/Default.o )
    [21 of 23] Compiling Data.Extensible.Dictionary ( src/Data/Extensible/Dictionary.hs, .stack-work/dist/x86_64-osx/Cabal-2.0.1.0/build/Data/Extensible/Dictionary.o )

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:104:98: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a6
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    104 |     = ENUM_EACH(\i -> G.basicUnsafeCopy (hlookupC i v) (hlookupC i w))
        |                                                                                                  ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:119:127: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a0
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    119 |   basicInitialize (MV_Product v) = ENUM_EACH(\i -> M.basicInitialize $ hlookupC i v)
        |                                                                                                                               ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:126:132: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a1
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    126 |   basicUnsafeWrite (MV_Product v) i x = ENUM_EACH(\m -> M.basicUnsafeWrite (hlookupC m v) i (hlookup m x))
        |                                                                                                                                    ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:127:122: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a2
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    127 |   basicClear (MV_Product v) = ENUM_EACH(\i -> M.basicClear $ hlookupC i v)
        |                                                                                                                          ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:128:122: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a3
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    128 |   basicSet (MV_Product v) x = ENUM_EACH(\i -> M.basicSet (hlookupC i v) (hlookup i x))
        |                                                                                                                          ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:130:98: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a4
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    130 |     = ENUM_EACH(\i -> M.basicUnsafeCopy (hlookupC i v1) (hlookupC i v2))
        |                                                                                                  ^^^^

    /private/var/folders/x3/4hf6y2j97xx_4y57ds425v_r0000gn/T/stack52512/extensible-0.4.7/src/Data/Extensible/Dictionary.hs:132:98: error:
        • Variable not in scope: expr :: Membership (x : xs) x1 -> m a5
        • Perhaps you meant ‘exp’ (imported from Prelude)
        |
    132 |     = ENUM_EACH(\i -> M.basicUnsafeMove (hlookupC i v1) (hlookupC i v2))
        |                                                                                                  ^^^^

Cannot build with hashable-1.4.0.0

When build extensible (0.8.3) with hashable-1.4.0.0, occur error:

[17 of 19] Compiling Data.Extensible.Dictionary
                          
/path/to/extensible/src/Data/Extensible/Dictionary.hs:108:10: error:
    • Could not deduce (Forall (Instance1 Eq h) xs)
        arising from the superclasses of an instance declaration
      from the context: WrapForall Hashable h xs
        bound by the instance declaration
        at src/Data/Extensible/Dictionary.hs:108:10-55
    • In the instance declaration for ‘Hashable (xs :& h)’
    |                     
108 | instance WrapForall Hashable h xs => Hashable (xs :& h) where
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                          
/path/to/extensible/src/Data/Extensible/Dictionary.hs:264:10: error:
    • Could not deduce (Forall (Instance1 Eq h) xs)
        arising from the superclasses of an instance declaration
      from the context: WrapForall Hashable h xs
        bound by the instance declaration
        at src/Data/Extensible/Dictionary.hs:264:10-55
    • In the instance declaration for ‘Hashable (xs :/ h)’
    |                     
264 | instance WrapForall Hashable h xs => Hashable (xs :/ h) where
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Completed 48 action(s).   

hashable is changed to add Eq constraint for Hashable class at version 1.4.0.0 haskell-unordered-containers/hashable#202
So, I think need change to:

--- a/src/Data/Extensible/Dictionary.hs
+++ b/src/Data/Extensible/Dictionary.hs
@@ -105,7 +105,7 @@ instance (WrapForall Semigroup h xs, WrapForall Monoid h xs) => Monoid (xs :& h)
   mappend = (<>)
   {-# INLINE mappend #-}
 
-instance WrapForall Hashable h xs => Hashable (xs :& h) where
+instance (WrapForall Eq h xs, WrapForall Hashable h xs) => Hashable (xs :& h) where
   hashWithSalt = hfoldlWithIndexFor (Proxy :: Proxy (Instance1 Hashable h))
     (const hashWithSalt)
   {-# INLINE hashWithSalt #-}
@@ -261,7 +261,7 @@ instance WrapForall NFData h xs => NFData (xs :/ h) where
   rnf (EmbedAt i h) = views (pieceAt i) (\(Compose Dict) -> rnf h) (library :: xs :& Compose Dict (Instance1 NFData h))
   {-# INLINE rnf #-}
 
-instance WrapForall Hashable h xs => Hashable (xs :/ h) where
+instance (WrapForall Eq h xs, WrapForall Hashable h xs) => Hashable (xs :/ h) where
   hashWithSalt s (EmbedAt i h) = views (pieceAt i)
     (\(Compose Dict) -> s `hashWithSalt` i `hashWithSalt` h)
     (library :: xs :& Compose Dict (Instance1 Hashable h))

Tutorial on how to use effects

Hi, during investigating topic of Free monads, I have found your blog post about performance of extensible. I have found it interesting and tried to start using, but struggling to do it.
Other libraries has more examples to compare.
For example, I can't get into how to implement with extensible the example for freer:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE DataKinds #-}
module Console where

import Control.Monad.Freer
import Control.Monad.Freer.Internal
import System.Exit hiding (ExitSuccess)

--------------------------------------------------------------------------------
                               -- Effect Model --
--------------------------------------------------------------------------------
data Console s where
    PutStrLn    :: String -> Console ()
    GetLine     :: Console String
    ExitSuccess :: Console ()

putStrLn' :: Member Console r => String -> Eff r ()
putStrLn' = send . PutStrLn

getLine' :: Member Console r => Eff r String
getLine' = send GetLine

exitSuccess' :: Member Console r => Eff r ()
exitSuccess' = send ExitSuccess

--------------------------------------------------------------------------------
                          -- Effectful Interpreter --
--------------------------------------------------------------------------------
runConsole :: Eff '[Console] w -> IO w
runConsole (Val x) = return x
runConsole (E u q) =
    case extract u of
        PutStrLn msg -> putStrLn msg >>  runConsole (qApp q ())
        GetLine      -> getLine      >>= \s -> runConsole (qApp q s)
        ExitSuccess  -> exitSuccess

--------------------------------------------------------------------------------
                             -- Pure Interpreter --
--------------------------------------------------------------------------------
runConsolePure :: [String] -> Eff '[Console] w -> [String]
runConsolePure inputs req =
    reverse . snd $ run (handleRelayS (inputs, []) (\s _ -> pure s) go req)
  where
    go  :: ([String], [String])
        -> Console v
        -> (([String], [String]) -> Arr '[] v ([String], [String]))
        -> Eff '[] ([String], [String])
    go (is,   os) (PutStrLn msg) q = q (is, msg : os) ()
    go (i:is, os) GetLine        q = q (is, os) i
    go ([],   _ ) GetLine        _ = error "Not enough lines"
    go (_,    os) ExitSuccess    _ = pure ([], os)

I am aware of extensible's example/effects.hs, but it does not compiling:

/mnt/localdata/share/devel/haskell/ext-test/app/Main.hs:43:27: error:
    • Expected kind ‘[Assoc * (* -> *)]’,
        but ‘Example’ has kind ‘[Assoc
                                   ghc-prim-0.5.1.1:GHC.Types.Symbol (* -> *)]’
    • In the first argument of ‘Methods’, namely ‘Example’
      In the type signature: example :: Int -> Methods Example IO
   |
43 | example :: Int -> Methods Example IO
   |                           ^^^^^^^

Why don't you use GHC's Custom Type Error?

The mechanism of indicating error using Elaborate type family is quite cool but now that extensible doesn't support older GHC, it can use GHC.TypeError to show more readable error messages. How do you think of it?

Example: I experimentally implemented it and found it useful when I can't remember the name of the field.

Can't use hfoldMap with show

I'm evaluated this package so I've been trying a few thing on the repl.
I would like to transform a record to a list of string for that I'm using hfoldmap. I can't get it to compile and get the following error message

(hfoldMap (show .  getField)) :: Forall (KeyValue KnownSymbol Show) xs => Record xs -> String

<interactive>:647:12: error:
    • Could not deduce (Show (AssocValue x))
        arising from a use of ‘show’
      from the context: Forall (KeyValue KnownSymbol Show) xs
        bound by the inferred type of
                 it :: Forall (KeyValue KnownSymbol Show) xs => Record xs -> String
        at <interactive>:647:1-93
      or from: Forall (KeyValue KnownSymbol Show) xs1
        bound by an expression type signature:
                   Forall (KeyValue KnownSymbol Show) xs1 => Record xs1 -> String
        at <interactive>:647:1-93
    • In the first argument of ‘(.)’, namely ‘show’
      In the first argument of ‘hfoldMap’, namely ‘(show . getField)’
      In the expression:
          (hfoldMap (show . getField)) ::
            Forall (KeyValue KnownSymbol Show) xs => Record xs -> String

(I know this is not the exact code I need, but I should be able to get what I want, once I get that to compile).

Is it possible to make it work ?

Thanks/

[question]How to implement a standard effect handler?

I want to implement an effect handler, using operation pattern-matching with continuations.
For example, here is a simple state example:

interface State s = Get : s | Put : s -> ()

state : Eff [State a] r -> a -> r
state = \case
  value r -> \_ -> r
  <Get -> k> -> \s -> state (k s) s
  <Put s' -> k> -> \_ -> state (k ()) s'

In this example, type of the two continuation k in case pattern should be a -> Eff [State a] r and () -> Eff [State a] r.

However, peelEff has type Rebinder xs r -> (a -> r) -> (forall x. t x -> (x -> r) -> r) -> Eff ((k >: t) ': xs) a -> r, this seems not fit in this example.
The type of operation handling function should be forall x. t x -> (x -> Eff xs r) -> r.

So how to implement this effect handler in extensible?

Why not defined type family `(++)` of Record and Variant

type family (++) of type lebel list is defined in extensible.

But, undefined (++) for Record and Variant.
if defined one, We can write below code:

type A = Record '[ "aaa" >: Bool ]
type B = A ++ Record '[ "bbb" >: Bool ]

Of course, We can define A and B after defining the type of fields type FieldA = '["aaa">: Bool] without one.
But, I think that it's more useful if (++) for Record is defined.

I think that it's easy to define using PolyKInds.

type family (++) (t1 :: a) (t2 :: a) :: a where
  '[] ++ ys = ys
  (x ': xs) ++ ys = x ': xs ++ ys
  (h :* xs) ++ (h :* ys) = h :* (xs ++ ys)
  (h :| xs) ++ (h :| ys) = h :| (xs ++ ys)

Can I create a PR ?

Accumulation of sums reverses element order

The type of accumulation operator taken by haccum (it's ... -> g x -> h x -> h x) suggests right fold will be performed, while in fact haccum performs left fold.

This mismatch is evident with hpartition function - element order gets reversed:

embedInt :: Int -> '[Int] :/ Identity
embedInt x  = EmbedAt membership (Identity x)

items :: ['[Int] :/ Identity]
items = embedInt <$> [1,2,3]

y :: '[Int] :& Compose [] Identity
y = hpartition id items

-- >>> y
-- Compose [Identity 3,Identity 2,Identity 1] <: nil

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.