dhall-lang / dhall-text

This repository has moved to https://github.com/dhall-lang/dhall-haskell/tree/master/dhall-text
BSD 3-Clause "New" or "Revised" License
21 stars 3 forks source link

Use within Haskell ? #8

Open revskill10 opened 6 years ago

revskill10 commented 6 years ago

How to use library within Haskell as a html or json templating engine ? Note: I can't access ipfs functions, the host takes to long to respond.

Gabriella439 commented 6 years ago

@checkraiser: See this line which is the key step:

https://github.com/dhall-lang/dhall-text/blob/baa335848c6c425fbf9705ca4ca2bf4c7cc4e0ad/exec/Main.hs#L59

The dhall-to-text executable uses the Interpret instance for Text to read the configuration in directly as a Text value using Dhall.input, so you can do the same thing in your code.

I'm planning on moving off of IPFS onto GitHub (See: https://github.com/dhall-lang/dhall-lang/issues/162) but I'll also try to redeploy the IPFS mirror for the Dhall prelude as soon as I can.

revskill10 commented 6 years ago

@Gabriel439 How about separating function and input ? function is for generating output, and input are our Haskell data type.

Gabriella439 commented 6 years ago

@checkraiser: Can you clarify what you mean by function?

revskill10 commented 6 years ago

@Gabriel439 Sorry for delaying. My use case is to use dhall as html template, so we can use to return html response to user in a web application. For this to work, we have to load dhall function dynamically and call it with our Haskell content to generate html. Am i right ?

Gabriella439 commented 6 years ago

@checkraiser: You can load some Dhall functions into Haskell, with some restrictions:

Here is an example. Suppose that you have the following Dhall function to template HTML:

-- example.dhall

  λ(greeting : Text)
→ λ(name : Text)
→ ''
  <html>
  <body>
  ${greeting}, ${name}!
  </body>
  </html>
  ''

Then you can load that function into Haskell and use it to template the HTML with different values:

Prelude Dhall> f <- input auto "./example.dhall" :: IO (Text -> Text -> Text)
Prelude Dhall> f "Hello" "John"
"<html>\n<body>\nHello, John!\n</body>\n</html>\n"

You can also pass Haskell data types to the function that you use to template the HTML. The above trick works for any function argument that implements the Inject class and you can derive Inject for your Haskell data types.

For example, suppose that we change our Dhall code to:

-- example.dhall

  λ(record : { greeting : Text, name : Text })
→ ''
  <html>
  <body>
  ${record.greeting}, ${record.name}!
  </body>
  </html>
  ''

You can supply a Haskell record as an input to that function like this:

{-# LANGUAGE DeriveGeneric     #-}
{-# LANGUAGE DeriveAnyClass    #-}
{-# LANGUAGE OverloadedStrings #-}

import Data.Text (Text)
import Dhall (Generic, Inject)

import qualified Data.Text.IO
import qualified Dhall

data Record = Record { greeting :: Text, name :: Text }
    deriving (Generic, Inject)

main :: IO ()
main = do
    function <- Dhall.input Dhall.auto "./example.dhall"
    Data.Text.IO.putStr (function (Record { greeting = "Hello", name = "John" }))