Join GitHub today
GitHub is home to over 36 million developers working together to host and review code, manage projects, and build software together.
Sign upMultiline strings and string interpolation #47
Comments
This comment has been minimized.
This comment has been minimized.
|
Newer versions of Dhall support multiline strings using the same syntax and semantics as Nix, like this: { example = ''
This is a multi-line
string that will have leading
indentation stripped
''
}However, Dhall doesn't support string interpolation yet, but I'm happy to add that |
This comment has been minimized.
This comment has been minimized.
|
Thank you, that would be great! Could you give a rough time line on when that feature will be available? |
This comment has been minimized.
This comment has been minimized.
|
I think @Gabriel439 didn't have a close look at what you are interpolating ;) I don't think that we will ever allow interpolation of Haskell code. (Correct me Gabriel if I'm wrong) What could be supported as string interpolation is to have
to get
|
This comment has been minimized.
This comment has been minimized.
|
@markus1189 You are right, I wrote the example in Haskell syntax, but I only want to express rendering a data type. I never worked with dhall before, so maybe I got this wrong, but shouldn't it be possible to write a function that takes a record and returns a string? Not
|
This comment has been minimized.
This comment has been minimized.
|
That should be fine :)
…On May 5, 2017 21:59, "Anton Felix Lorenzen" ***@***.***> wrote:
@markus1189 <https://github.com/markus1189> You are right, I wrote the
example in Haskell syntax, but I only want to express rendering a data
type. I never worked with dhall before, so maybe I got this wrong, but
shouldn't it be possible to write a function that takes a record and
returns a string? Not show, more something in the form of:
let renderRating rating = ''
# My thoughts about ${rating.name} (${rating.rating} out of 5)
''
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#47 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAkGz8dMtTwFoDVajHOF-LXMbujLjj2rks5r23-tgaJpZM4NRtFU>
.
|
This comment has been minimized.
This comment has been minimized.
|
Yeah, @markus1189 is correct and I meant interpolating My only caveat is that I might require the interpolated value to be { example = "${Natural/toText (+1 + +2)}" }That would imply that if you want to display a I estimate this would conservatively take a few weeks for me to implement based on my upcoming schedule |
This comment has been minimized.
This comment has been minimized.
|
Also, as a side note, I've been considering releasing a small |
This comment has been minimized.
This comment has been minimized.
|
No, I don't need such an utility as I use the Entry constructor fields for some features (page title and meta information, twitter cards, sidemaps, etc.). |
This comment has been minimized.
This comment has been minimized.
|
@Gabriel439 what do you think about opening an issue that collects the status of implementing string interpolation? If I can I might implement some of the We could even track the progress via a TODO list, s.t. anybody can jump in and give it a try |
This comment has been minimized.
This comment has been minimized.
|
@markus1189: Sure! However, there are two things worth noting: First, there are a couple of primitives don't require primitive support. For example, you can do λ(b : Bool) → if b then "True" else "False"... and showing λ(a : Type)
→ λ(showElement : a → Text)
→ λ(xs : List a)
→ let interior
= List/fold
a
xs
Text
(λ(y : a) → λ(ys : Text) → showElement y ++ ", " ++ ys)
""
in "[" ++ interior ++ "]"... and you can also do it without trailing commas with a little extra complexity: λ(a : Type)
→ λ(showElement : a → Text)
→ λ(xs : List a)
→ let interior
= List/fold
a
xs
< Empty : {} | NonEmpty : Text >
( λ(y : a)
→ λ(ys : < Empty : {} | NonEmpty : Text >)
→ merge
{ Empty
= λ(_ : {})
→ < NonEmpty = showElement y | Empty : {} >
, NonEmpty
= λ(z : Text)
→ < NonEmpty = showElement y ++ ", " ++ z | Empty : {} >
}
ys : < Empty : {} | NonEmpty : Text >
)
< Empty = {=} | NonEmpty : Text >
in merge
{ Empty = λ(_ : {}) → "[]"
, NonEmpty = λ(z : Text) → "[" ++ z ++ "]"
}
interior : Text... although they aren't too efficient. They take a few seconds to render 1000 elements on my laptop so it might still be worth providing primitives if we can't optimize that Second, the above code is actually wrong because you can't display an empty let Show : ∀(a : Type) → Type
= λ(a : Type) → { show : a → Text, type : Text }
in ShowSo, for example a let showBool : ./Show Bool
= { show = λ(b : Bool) → if b then "True" else "False"
, type : "Bool"
}
in showBoolHowever, it's actually even more complicated than that because you need to keep track of when to display parentheses. For example, if you do: -- Assuming
-- ./showList : ∀(a : Type) → ./Show a → ./Show (List a)
-- ./showBool : ./Show Bool
./showList (List Bool) (./showList Bool ./showBool)... then you want to make sure that the type gets rendered correctly as: List (List Bool)... and not: List List Bool... and implementing that correctly within Dhall is possible, but tricky |
This comment has been minimized.
This comment has been minimized.
|
@Gabriel439, I am glad to see that you are working on this. However, a let renderRating rating = ''
# My thoughts about ${rating.name} (${showNat rating.rating} out of 5)
''Here, the rating can't drop below zero, so you could model So, unless it conflicts with your vision for dhall, I would suggest we implement @markus1189's proposal and have a TODO list, so I could implement the things that are the most relevant for me, if you don't mind. |
This comment has been minimized.
This comment has been minimized.
|
Right, I understand that whether or not to provide a However, I don't think λ(rating : { name : Text, rating : Natural }) → ''
# My thoughts about ${rating.name} (${Integer/show (Natural/toInteger rating.rating)} out of 5)Also, I realized that there is no need to worry about rendering different bases (i.e. binary/hexademical/etc.) since the scope of a
That should probably solve @anfelor's use case and I'm pretty sure we will need those functions no matter what higher-level interface we provide in the Prelude |
This comment has been minimized.
This comment has been minimized.
|
Also, thinking more about what @anfelor said, in most cases users will not want a utility to show lists in the exact same form as Dhall, or anything even remotely close. Typically they will want to template items using their own list format, like this for example: let concat = https://ipfs.io/ipfs/QmcTbCdS21pCxXysTzEiucDuwwLWbLUWNSKwkJVfwpy2zK/Prelude/Text/concat
in let map = https://ipfs.io/ipfs/QmcTbCdS21pCxXysTzEiucDuwwLWbLUWNSKwkJVfwpy2zK/Prelude/List/map
in λ(items : List Text)
→ "List of items:\n"
++ concat (map Text Text (λ(x : Text) → "* " ++ x ++ "\n") items) |
This comment has been minimized.
This comment has been minimized.
|
@Gabriel439, yes, for example, I am currently thinking whether to write the html as a dhall template. In that case, I would implement something like your code above. |
Gabriel439
added a commit
that referenced
this issue
May 22, 2017
This comment has been minimized.
This comment has been minimized.
|
Sorry it took a while, but I finally have an implementation ready here: #60 Let me know if that is what you had in mind |
anfelor commentedMay 5, 2017
I am currently writing a blog system with Haskell and I store the posts as Haskell values:
The benefit of this is, that I can add extra information like keywords and rely on the type checker to check that they are valid (for example using the keyword "Bloging" would be a compile-time error).
The reason I don't use pandoc filters for this is that I want use arbitrary Haskell data types in the quasiquote via an escaping mechanism allowing me to implement microformats and schema.org markup with ease. The problem is that I will have to use haskell-src-exts as an additional dependency for that.
So I am currently looking at dhall as an alternative for that use case. I would write a blog entry in a dhall file as an Entry data type and import the files into Haskell. However, I need multi-line strings (like in the md quasi-quote above) and string interpolation in the form of
As this is probably not an uncommon requirement for a configuration language, I wanted to ask whether it would make sense to add these features.