dhall-text icon indicating copy to clipboard operation
dhall-text copied to clipboard

Use within Haskell ?

Open revskill10 opened this issue 7 years ago • 5 comments

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.

revskill10 avatar Jun 18 '18 09:06 revskill10

@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.

Gabriella439 avatar Jun 18 '18 15:06 Gabriella439

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

revskill10 avatar Jun 18 '18 21:06 revskill10

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

Gabriella439 avatar Jun 18 '18 22:06 Gabriella439

@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 ?

revskill10 avatar Jul 04 '18 12:07 revskill10

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

  • They cannot be polymorphic functions (i.e. none of the function arguments can be types)
  • They cannot be higher-order functions (i.e. none of the function arguments can be functions)

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" }))

Gabriella439 avatar Jul 04 '18 14:07 Gabriella439