Text Templates in Idris

import Data.String

-- We can create a new template and parse its body from
-- a string.
-- Templates are a mix of static text and "holes" enclosed in
-- {{...}} that are used to dynamically insert content.
t1 : String -> String
t1 value = "Value is " ++ value ++ "\n"

-- By "executing" the template we generate its text with
-- specific values for its actions. The {{.}} action is
-- replaced by the value passed as a parameter to Execute.
main : IO ()
main = do
    putStr $ t1 "some text"
    putStr $ t1 (show 5)
    putStr $ t1 (show ["Idris", "Haskell", "Agda", "Coq"])

-- If the data is a record we can use the {{.FieldName}} action to access
-- its fields. In Idris, we'll use a function that takes a record as input.
record Person where
    constructor MkPerson
    name : String

t2 : Person -> String
t2 person = "Name: " ++ person.name ++ "\n"

-- The same applies to dictionaries; with dictionaries there is no restriction on the
-- case of key names.
t2Dict : List (String, String) -> String
t2Dict dict = case lookup "Name" dict of
    Just name -> "Name: " ++ name ++ "\n"
    Nothing -> "Name not found\n"

-- if/else provide conditional execution for templates. A value is considered
-- false if it's an empty string.
t3 : String -> String
t3 str = if str /= "" then "yes\n" else "no\n"

-- range blocks let us loop through lists. In Idris, we'll use list comprehension.
t4 : List String -> String
t4 list = "Range: " ++ unwords list ++ "\n"

-- Helper function to print the results
printResult : String -> IO ()
printResult = putStr

main : IO ()
main = do
    printResult $ t1 "some text"
    printResult $ t1 (show 5)
    printResult $ t1 (show ["Idris", "Haskell", "Agda", "Coq"])
    
    printResult $ t2 (MkPerson "Jane Doe")
    
    printResult $ t2Dict [("Name", "Mickey Mouse")]
    
    printResult $ t3 "not empty"
    printResult $ t3 ""
    
    printResult $ t4 ["Idris", "Haskell", "Agda", "Coq"]

This Idris code demonstrates the equivalent functionality of the original example. Here’s a brief explanation of the changes:

  1. Idris doesn’t have a built-in templating system like Go’s text/template, so we’ve implemented simple functions that mimic the template behavior.

  2. The t1 function represents a simple template that inserts a value into a string.

  3. For struct/record access, we’ve defined a Person record and a function t2 that works with it.

  4. For map/dictionary access, we’ve used a List (String, String) and the lookup function to mimic the behavior.

  5. The conditional template (t3) is implemented as a simple if-else function.

  6. The range template (t4) uses list comprehension to join the elements of a list.

  7. Instead of using os.Stdout, we’re using Idris’s putStr function to print to the console.

  8. The main function demonstrates the usage of all these template-like functions.

To run this program, you would save it as a .idr file and use the Idris compiler:

$ idris -o templates templates.idr
$ ./templates

This will compile and run the Idris program, producing output similar to the original Go program.