clr-inline-0.1.0.0: src/Clr/FSharp/Inline.hs
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Clr.FSharp.Inline
( fsharp
, fsharp'
) where
import Clr.FSharp.Gen
import Clr.Inline.Config
import Clr.Inline.Quoter
import Language.Haskell.TH
import Language.Haskell.TH.Quote
-- | F# declaration and expression quasiquoter.
-- Declarations can include open statements, types or even modules.
-- Example declaration:
--
-- @
-- [fsharp|
-- open System
-- open System.Collections.Generic
-- module Globals =
-- let mutable today = DateTime.Today
-- |]
-- @
--
-- Expressions are wrapped in a curly braces block @{}@ that
-- fixes the return type. An F# expression quotation can refer to
-- a Haskell binding @x@ using the syntax @($x:type)@ where type is
-- a string denoting an F# type and is only required on the first usage, and the parentheses
-- are optional. F# types are mapped to Haskell types via the 'Quotable' class.
-- An antiquotation @$x:type@
-- is well-scoped if there exists a variable @x@ with a Haskell type @U@ in
-- the Haskell context such that there exists an instance
-- @Quotable type clr marshall U@ for some @clr@ and @marshall@.
--
-- An F# expression returns an IO computation that
-- produces a value of the quoted result type if said type is 'Quotable'.
-- Example expressions:
--
-- @
-- hello :: IO (Int, Clr \"System.DateTime")
-- hello = do
-- let year = 2017 :: Int
-- aClr <- [fsharp| DateTime{ DateTime($year:int,04,10)} |]
-- anInt <- [fsharp| int{ ($aClr:System.DateTime).Year + $year:int + $year}|]
-- return (anInt, anClr)
-- @
--
-- CLR Reference types are modelled in Haskell as 'Clr' values, indexed with the
-- name of their F# type as a type level symbol. String equivalence is a poor
-- substitute for type equality, so for two 'Clr' values to have the same type
-- they must be indexed by exactly the same string.
--
-- This quasiquoter is implicitly configured with the 'defaultConfig'.
fsharp :: QuasiQuoter
fsharp = fsharp' defaultConfig
-- | Explicit configuration version of 'fsharp'.
fsharp' :: ClrInlineConfig -> QuasiQuoter
fsharp' cfg = QuasiQuoter
{ quoteExp = fsharpExp cfg
, quotePat = error "Clr.FSharp.Inline: quotePat"
, quoteType = error "Clr.FSharp.Inline: quoteType"
, quoteDec = fsharpDec cfg
}
fsharpExp :: ClrInlineConfig -> String -> Q Exp
fsharpExp cfg =
clrQuoteExp
name
(compile cfg)
fsharpDec :: ClrInlineConfig -> String -> Q [Dec]
fsharpDec = clrQuoteDec name . compile