Skip to content

Conversation

@kcsongor
Copy link
Contributor

@kcsongor kcsongor commented Aug 27, 2017

This adds and solves a new 'magic' constraint,
Type.Data.Symbol.ConsSymbol, with the following functional
dependencies:

class ConsSymbol (head :: Symbol)
                 (tail :: Symbol)
                 (sym :: Symbol) | sym -> head tail, head tail -> sym
  • The head tail -> sym direction works like AppendSymbol, but only
    resolves when head is a singleton symbol.

  • The sym -> head tail direction deconstructs the symbol into its
    first character and the remaining string.

The relevant PR for the typelevel-prelude:
purescript/purescript-typelevel-prelude#24

I put up an example that uses this class at
https://github.com/kcsongor/purescript-record-format

This adds and solves a new 'magic' constraint,
`Type.Data.Symbol.ConsSymbol`, with the following functional
dependencies:

class ConsSymbol (head :: Symbol)
                 (tail :: Symbol)
                 (sym :: Symbol) | sym -> head tail, head tail -> sym

* The `head tail -> sym` direction works like `AppendSymbol`, but only
resolves when `head` is a singleton symbol.

* The `sym -> head tail` direction deconstructs the symbol into its
first character and the remaining string.
@kcsongor
Copy link
Contributor Author

I'd be happy to add some examples, but I'm not too sure how I would depend on the new type-level prelude at this point

@kcsongor
Copy link
Contributor Author

Here's another example using it
https://github.com/kcsongor/purescript-safe-printf

let args = [arg0, arg1, TypeLevelString (lhs <> rhs)]
in [TypeClassDictionaryInScope AppendSymbolInstance [] C.AppendSymbol args Nothing]
forClassName _ C.ConsSymbol [arg0, arg1, arg2]
| Just (arg0', arg1', arg2') <- (consSymbol arg0 arg1 arg2) =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parens are redundant here.


consSymbol :: Type -> Type -> Type -> Maybe (Type, Type, Type)
consSymbol _ _ arg@(TypeLevelString s) = do
(h, t) <- (mkTLString . T.singleton *** mkTLString) <$> (T.uncons =<< decodeString s)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a little hard to read. What about this?

do (h, t) <- T.uncons =<< decodeString s
   pure (mkTLString (T.singleton h), mkTLString t, arg)

consSymbol arg1@(TypeLevelString h) arg2@(TypeLevelString t) _ = do
h' <- decodeString h
t' <- decodeString t
if (T.length h' == 1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could use guard here.

Copy link
Contributor

@paf31 paf31 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks! Couple of minor, non-blocking comments. I'll add this to the 0.12.0 queue.

@kcsongor
Copy link
Contributor Author

Thanks for the comments, I've fixed them!

@kcsongor
Copy link
Contributor Author

On a related note, I think it would be better to have a Char kind with type-level character literals, that way, it would become clearer what's happening here (and in type-level parsers too). What are your thoughts on this?

@paf31 paf31 merged commit 4289974 into purescript:master Sep 9, 2017
@paf31
Copy link
Contributor

paf31 commented Sep 9, 2017

Thanks!

We have some time before 0.12.0 is properly released to discuss the Char idea, so let's do that.

@paf31
Copy link
Contributor

paf31 commented Sep 9, 2017

@kcsongor Would you mind adding yourself to CONTRIBUTORS.md as well?

@kcsongor
Copy link
Contributor Author

Great, that sounds good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants