-- Copyright 2016 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | A static macro is like a "Derive.Call.Macro", except that its calls
-- are given directly in haskell, instead of looked up as strings during
-- evaluation.  This means that the calls can't be rebound, but on the other
-- hand, it can re-export the documentation for the sub-calls.
module Derive.Call.StaticMacro (
    Call(..), Arg(..), call, literal
    , check
    , generator, transformer
) where
import qualified Control.Monad.Identity as Identity
import qualified Control.Monad.State as Monad.State
import qualified Data.List as List
import qualified Data.Text as Text
import qualified Data.Tuple as Tuple

import qualified Util.CallStack as CallStack
import qualified Util.Doc as Doc
import qualified Util.Texts as Texts

import qualified Derive.Call.Module as Module
import qualified Derive.Call.Tags as Tags
import qualified Derive.Derive as Derive
import qualified Derive.DeriveT as DeriveT
import qualified Derive.Eval as Eval
import qualified Derive.ShowVal as ShowVal
import qualified Derive.Sig as Sig
import qualified Derive.Stream as Stream
import qualified Derive.Typecheck as Typecheck

import           Global


data Call call = Call !call ![Arg] deriving (Int -> Call call -> ShowS
forall call. Show call => Int -> Call call -> ShowS
forall call. Show call => [Call call] -> ShowS
forall call. Show call => Call call -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Call call] -> ShowS
$cshowList :: forall call. Show call => [Call call] -> ShowS
show :: Call call -> String
$cshow :: forall call. Show call => Call call -> String
showsPrec :: Int -> Call call -> ShowS
$cshowsPrec :: forall call. Show call => Int -> Call call -> ShowS
Show)
data Arg = Var | Given !Term deriving (Int -> Arg -> ShowS
[Arg] -> ShowS
Arg -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Arg] -> ShowS
$cshowList :: [Arg] -> ShowS
show :: Arg -> String
$cshow :: Arg -> String
showsPrec :: Int -> Arg -> ShowS
$cshowsPrec :: Int -> Arg -> ShowS
Show)
data Term = ValCall !Derive.ValCall ![Arg] | Literal !DeriveT.Val
    deriving (Int -> Term -> ShowS
[Term] -> ShowS
Term -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Term] -> ShowS
$cshowList :: [Term] -> ShowS
show :: Term -> String
$cshow :: Term -> String
showsPrec :: Int -> Term -> ShowS
$cshowsPrec :: Int -> Term -> ShowS
Show)

-- | A Term whose Vars have been filled in.
data ResolvedTerm =
    RValCall !Derive.ValCall ![ResolvedTerm] | RLiteral !DeriveT.Val
    deriving (Int -> ResolvedTerm -> ShowS
[ResolvedTerm] -> ShowS
ResolvedTerm -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ResolvedTerm] -> ShowS
$cshowList :: [ResolvedTerm] -> ShowS
show :: ResolvedTerm -> String
$cshow :: ResolvedTerm -> String
showsPrec :: Int -> ResolvedTerm -> ShowS
$cshowsPrec :: Int -> ResolvedTerm -> ShowS
Show)

call :: Derive.ValCall -> [Arg] -> Arg
call :: ValCall -> [Arg] -> Arg
call ValCall
c [Arg]
args = Term -> Arg
Given forall a b. (a -> b) -> a -> b
$ ValCall -> [Arg] -> Term
ValCall ValCall
c [Arg]
args

literal :: Typecheck.ToVal a => a -> Arg
literal :: forall a. ToVal a => a -> Arg
literal = Term -> Arg
Given forall b c a. (b -> c) -> (a -> b) -> a -> c
. Val -> Term
Literal forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. ToVal a => a -> Val
Typecheck.to_val

-- | Check the output of 'generator', 'transformer', or 'val' and crash if
-- it had a statically-detectable error.  Of course I'd much rather this
-- were a type error, but it's not worth breaking out TH for it.
check :: CallStack.Stack => Text -> Either Text a -> a
check :: forall a. HasCallStack => Text -> Either Text a -> a
check Text
call_name (Left Text
err) = forall a. HasCallStack => Text -> a
errorStack forall a b. (a -> b) -> a -> b
$ Text
call_name forall a. Semigroup a => a -> a -> a
<> Text
": " forall a. Semigroup a => a -> a -> a
<> Text
err
check Text
_ (Right a
val) = a
val

-- TODO implement it
require_val :: Sig.Arg -> Derive.Deriver DeriveT.Val
require_val :: Arg -> Deriver Val
require_val (Sig.SubTrack {}) =
    forall a. HasCallStack => Text -> Deriver a
Derive.throw Text
"child tracks don't work for macros yet"
require_val (Sig.LiteralArg Val
arg) = forall (m :: * -> *) a. Monad m => a -> m a
return Val
arg

-- | Create a generator macro from a list of transformers and a generator.
generator :: Derive.CallableExpr d => Module.Module -> Derive.CallName
    -> Tags.Tags -> Doc.Doc -> [Call (Derive.Transformer d)]
    -> Call (Derive.Generator d) -> Either Text (Derive.Generator d)
generator :: forall d.
CallableExpr d =>
Module
-> CallName
-> Tags
-> Doc
-> [Call (Transformer d)]
-> Call (Generator d)
-> Either Text (Generator d)
generator Module
module_ CallName
name Tags
tags Doc
doc [Call (Transformer d)]
trans Call (Generator d)
gen = do
    [ArgDoc]
trans_args <- forall (m :: * -> *) b a.
(Monad m, Monoid b) =>
(a -> m b) -> [a] -> m b
concatMapM forall f. Call (Call f) -> Either Text [ArgDoc]
extract_args [Call (Transformer d)]
trans
    [ArgDoc]
gen_args <- forall f. Call (Call f) -> Either Text [ArgDoc]
extract_args Call (Generator d)
gen
    let args :: [ArgDoc]
args = [ArgDoc]
trans_args forall a. [a] -> [a] -> [a]
++ [ArgDoc]
gen_args
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (GeneratorF d)
-> Generator d
Derive.generator Module
module_ CallName
name Tags
tags (Doc -> [Doc] -> Doc
make_doc Doc
doc [Doc]
call_docs) forall a b. (a -> b) -> a -> b
$
        forall y a d.
Taggable y =>
Parser a -> (a -> Generator y d) -> WithArgDoc (Generator y d)
Sig.call ([ArgDoc] -> Parser [Arg]
Sig.required_vals [ArgDoc]
args) forall a b. (a -> b) -> a -> b
$ \[Arg]
vals PassedArgs d
args -> do
            [Val]
vals <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Arg -> Deriver Val
require_val [Arg]
vals
            forall d.
CallableExpr d =>
[Call (Transformer d)]
-> Call (Generator d) -> [Val] -> Context d -> Deriver (Stream d)
generator_macro [Call (Transformer d)]
trans Call (Generator d)
gen [Val]
vals (forall val. PassedArgs val -> Context val
Derive.passed_ctx PassedArgs d
args)
    where call_docs :: [Doc]
call_docs = forall a b. (a -> b) -> [a] -> [b]
map forall f. Call (Call f) -> Doc
call_doc [Call (Transformer d)]
trans forall a. [a] -> [a] -> [a]
++ [forall f. Call (Call f) -> Doc
call_doc Call (Generator d)
gen]

generator_macro :: Derive.CallableExpr d => [Call (Derive.Transformer d)]
    -> Call (Derive.Generator d) -> [DeriveT.Val] -> Derive.Context d
    -> Derive.Deriver (Stream.Stream d)
generator_macro :: forall d.
CallableExpr d =>
[Call (Transformer d)]
-> Call (Generator d) -> [Val] -> Context d -> Deriver (Stream d)
generator_macro [Call (Transformer d)]
trans Call (Generator d)
gen [Val]
vals Context d
ctx = do
    let ([Transformer d]
tcalls, [[Arg]]
trans_args) = forall a b. [(a, b)] -> ([a], [b])
unzip (forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Call a -> (a, [Arg])
split [Call (Transformer d)]
trans)
    ([Val]
vals, [[ResolvedTerm]]
trans_args) <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL [Val] -> [Arg] -> ([Val], [ResolvedTerm])
substitute_vars [Val]
vals [[Arg]]
trans_args
    ([Val]
vals, [ResolvedTerm]
gen_args) <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ [Val] -> [Arg] -> ([Val], [ResolvedTerm])
substitute_vars [Val]
vals (forall a b. (a, b) -> b
snd (forall {a}. Call a -> (a, [Arg])
split Call (Generator d)
gen))
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Val]
vals) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => Text -> Deriver a
Derive.throw Text
"more args than $vars"
    [[Val]]
trans_args <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. Taggable a => Context a -> ResolvedTerm -> Deriver Val
eval_term Context d
ctx)) [[ResolvedTerm]]
trans_args
    [Val]
gen_args <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. Taggable a => Context a -> ResolvedTerm -> Deriver Val
eval_term Context d
ctx) [ResolvedTerm]
gen_args
    forall d.
Context d
-> [(Transformer d, [Val])]
-> Deriver (Stream d)
-> Deriver (Stream d)
Eval.apply_transformers Context d
ctx (forall a b. [a] -> [b] -> [(a, b)]
zip [Transformer d]
tcalls [[Val]]
trans_args) forall a b. (a -> b) -> a -> b
$
        forall d. Context d -> Generator d -> [Val] -> Deriver (Stream d)
Eval.apply_generator Context d
ctx (forall a b. (a, b) -> a
fst (forall {a}. Call a -> (a, [Arg])
split Call (Generator d)
gen)) [Val]
gen_args
    where
    split :: Call a -> (a, [Arg])
split (Call a
call [Arg]
args) = (a
call, [Arg]
args)

transformer :: Derive.CallableExpr d => Module.Module -> Derive.CallName
    -> Tags.Tags -> Doc.Doc -> [Call (Derive.Transformer d)]
    -- ^ Apply these transformers. This is in compose order, so the last one
    -- is applied first.
    -> Either Text (Derive.Transformer d)
transformer :: forall d.
CallableExpr d =>
Module
-> CallName
-> Tags
-> Doc
-> [Call (Transformer d)]
-> Either Text (Transformer d)
transformer Module
module_ CallName
name Tags
tags Doc
doc [Call (Transformer d)]
trans = do
    [ArgDoc]
args <- forall (m :: * -> *) b a.
(Monad m, Monoid b) =>
(a -> m b) -> [a] -> m b
concatMapM forall f. Call (Call f) -> Either Text [ArgDoc]
extract_args [Call (Transformer d)]
trans
    forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall d.
Module
-> CallName
-> Tags
-> Doc
-> WithArgDoc (TransformerF d)
-> Transformer d
Derive.transformer Module
module_ CallName
name Tags
tags (Doc -> [Doc] -> Doc
make_doc Doc
doc [Doc]
call_docs) forall a b. (a -> b) -> a -> b
$
        forall y a d.
Taggable y =>
Parser a -> (a -> Transformer y d) -> WithArgDoc (Transformer y d)
Sig.callt ([ArgDoc] -> Parser [Arg]
Sig.required_vals [ArgDoc]
args) forall a b. (a -> b) -> a -> b
$ \[Arg]
vals PassedArgs d
args Deriver (Stream d)
deriver -> do
            [Val]
vals <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Arg -> Deriver Val
require_val [Arg]
vals
            forall d.
CallableExpr d =>
[Call (Transformer d)]
-> [Val] -> Context d -> Deriver (Stream d) -> Deriver (Stream d)
transformer_macro [Call (Transformer d)]
trans [Val]
vals (forall val. PassedArgs val -> Context val
Derive.passed_ctx PassedArgs d
args) Deriver (Stream d)
deriver
    where call_docs :: [Doc]
call_docs = forall a b. (a -> b) -> [a] -> [b]
map forall f. Call (Call f) -> Doc
call_doc [Call (Transformer d)]
trans

transformer_macro :: Derive.CallableExpr d => [Call (Derive.Transformer d)]
    -> [DeriveT.Val] -> Derive.Context d
    -> Derive.Deriver (Stream.Stream d) -> Derive.Deriver (Stream.Stream d)
transformer_macro :: forall d.
CallableExpr d =>
[Call (Transformer d)]
-> [Val] -> Context d -> Deriver (Stream d) -> Deriver (Stream d)
transformer_macro [Call (Transformer d)]
trans [Val]
vals Context d
ctx Deriver (Stream d)
deriver = do
    let ([Transformer d]
tcalls, [[Arg]]
trans_args) = forall a b. [(a, b)] -> ([a], [b])
unzip (forall a b. (a -> b) -> [a] -> [b]
map forall {a}. Call a -> (a, [Arg])
split [Call (Transformer d)]
trans)
    ([Val]
vals, [[ResolvedTerm]]
trans_args) <- forall (m :: * -> *) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$
        forall (t :: * -> *) s a b.
Traversable t =>
(s -> a -> (s, b)) -> s -> t a -> (s, t b)
List.mapAccumL [Val] -> [Arg] -> ([Val], [ResolvedTerm])
substitute_vars [Val]
vals [[Arg]]
trans_args
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Val]
vals) forall a b. (a -> b) -> a -> b
$ forall a. HasCallStack => Text -> Deriver a
Derive.throw Text
"more args than $vars"
    [[Val]]
trans_args <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. Taggable a => Context a -> ResolvedTerm -> Deriver Val
eval_term Context d
ctx)) [[ResolvedTerm]]
trans_args
    forall d.
Context d
-> [(Transformer d, [Val])]
-> Deriver (Stream d)
-> Deriver (Stream d)
Eval.apply_transformers Context d
ctx (forall a b. [a] -> [b] -> [(a, b)]
zip [Transformer d]
tcalls [[Val]]
trans_args) Deriver (Stream d)
deriver
    where
    split :: Call a -> (a, [Arg])
split (Call a
call [Arg]
args) = (a
call, [Arg]
args)

eval_term :: Derive.Taggable a => Derive.Context a -> ResolvedTerm
    -> Derive.Deriver DeriveT.Val
eval_term :: forall a. Taggable a => Context a -> ResolvedTerm -> Deriver Val
eval_term Context a
_ (RLiteral Val
val) = forall (m :: * -> *) a. Monad m => a -> m a
return Val
val
eval_term Context a
ctx (RValCall ValCall
call [ResolvedTerm]
terms) = do
    [Val]
vals <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (forall a. Taggable a => Context a -> ResolvedTerm -> Deriver Val
eval_term Context a
ctx) [ResolvedTerm]
terms
    let passed :: PassedArgs Tagged
passed = Derive.PassedArgs
            { passed_vals :: [Val]
passed_vals = [Val]
vals
            , passed_call_name :: CallName
passed_call_name = ValCall -> CallName
Derive.vcall_name ValCall
call
            , passed_ctx :: Context Tagged
passed_ctx = forall a. Taggable a => Context a -> Context Tagged
Derive.tag_context Context a
ctx
            }
    ValCall -> PassedArgs Tagged -> Deriver Val
Derive.vcall_call ValCall
call PassedArgs Tagged
passed

-- | Substitute the given Vals into the non-'Given' Args.
substitute_vars :: [DeriveT.Val] -> [Arg] -> ([DeriveT.Val], [ResolvedTerm])
    -- ^ (remaining_vals, substituted)
substitute_vars :: [Val] -> [Arg] -> ([Val], [ResolvedTerm])
substitute_vars [Val]
all_vals [Arg]
args = forall {a}. StateT [Val] Identity a -> ([Val], a)
run (forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Arg -> StateT [Val] Identity ResolvedTerm
subst_arg [Arg]
args)
    where
    subst_arg :: Arg -> StateT [Val] Identity ResolvedTerm
subst_arg Arg
arg = case Arg
arg of
        Arg
Var -> Val -> ResolvedTerm
RLiteral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> StateT [Val] Identity Val
pop
        Given (Literal Val
val) -> forall (m :: * -> *) a. Monad m => a -> m a
return (Val -> ResolvedTerm
RLiteral Val
val)
        Given (ValCall ValCall
call [Arg]
args) -> ValCall -> [ResolvedTerm] -> ResolvedTerm
RValCall ValCall
call forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Arg -> StateT [Val] Identity ResolvedTerm
subst_arg [Arg]
args
    pop :: StateT [Val] Identity Val
pop = do
        [Val]
vals <- forall s (m :: * -> *). MonadState s m => m s
Monad.State.get
        case [Val]
vals of
            -- This allows the sub-call look in the environ for a default.
            [] -> forall (m :: * -> *) a. Monad m => a -> m a
return Val
DeriveT.VNotGiven
            Val
v : [Val]
vs -> forall s (m :: * -> *). MonadState s m => s -> m ()
Monad.State.put [Val]
vs forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall (m :: * -> *) a. Monad m => a -> m a
return Val
v
    run :: StateT [Val] Identity a -> ([Val], a)
run = forall a b. (a, b) -> (b, a)
Tuple.swap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Identity a -> a
Identity.runIdentity
        forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall s (m :: * -> *) a. StateT s m a -> s -> m (a, s)
Monad.State.runStateT [Val]
all_vals

-- Look for Vars, and get the corresponding ArgDoc.
extract_args :: Call (Derive.Call f) -> Either Text [Derive.ArgDoc]
extract_args :: forall f. Call (Call f) -> Either Text [ArgDoc]
extract_args (Call Call f
call [Arg]
args) = CallDoc -> [Arg] -> Either Text [ArgDoc]
extract (forall func. Call func -> CallDoc
Derive.call_doc Call f
call) [Arg]
args
    where
    extract :: Derive.CallDoc -> [Arg] -> Either Text [Derive.ArgDoc]
    extract :: CallDoc -> [Arg] -> Either Text [ArgDoc]
extract CallDoc
cdoc [Arg]
args
        | forall (t :: * -> *) a. Foldable t => t a -> Int
length [Arg]
args forall a. Ord a => a -> a -> Bool
> forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgDoc]
docs = forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$
            Text
"call can take up to " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt (forall (t :: * -> *) a. Foldable t => t a -> Int
length [ArgDoc]
docs)
            forall a. Semigroup a => a -> a -> a
<> Text
" args, but was given " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> Text
showt (forall (t :: * -> *) a. Foldable t => t a -> Int
length [Arg]
args)
        | Bool
otherwise = forall (m :: * -> *) b a.
(Monad m, Monoid b) =>
(a -> m b) -> [a] -> m b
concatMapM (ArgDoc, Arg) -> Either Text [ArgDoc]
extract_arg (forall a b. [a] -> [b] -> [(a, b)]
zip [ArgDoc]
docs [Arg]
args)
        where
        docs :: [ArgDoc]
docs = CallDoc -> [ArgDoc]
Derive.cdoc_args CallDoc
cdoc
        extract_arg :: (ArgDoc, Arg) -> Either Text [ArgDoc]
extract_arg (ArgDoc
doc, Arg
arg) = case Arg
arg of
            Arg
Var -> forall a b. b -> Either a b
Right [ArgDoc
doc]
            Given (Literal Val
_) -> forall a b. b -> Either a b
Right []
            Given (ValCall ValCall
call [Arg]
args) -> CallDoc -> [Arg] -> Either Text [ArgDoc]
extract (ValCall -> CallDoc
Derive.vcall_doc ValCall
call) [Arg]
args

-- ** doc

make_doc :: Doc.Doc -> [Doc.Doc] -> Doc.Doc
make_doc :: Doc -> [Doc] -> Doc
make_doc Doc
doc [Doc]
calls = forall a. Textlike a => a -> a -> a
Texts.unlines2 Doc
doc forall a b. (a -> b) -> a -> b
$
    Doc
"A static macro for: `" forall a. Semigroup a => a -> a -> a
<> forall a. Textlike a => a -> [a] -> a
Texts.join Doc
" | " [Doc]
calls forall a. Semigroup a => a -> a -> a
<> Doc
"`.\
    \\nEach `$` is lifted to be an argument of this macro.\
    \\nThis directly calls the underlying sub-calls, so it's not dependent on\
    \ the names they are bound to, which also means the macro text may not be a\
    \ valid expression."

call_doc :: Call (Derive.Call f) -> Doc.Doc
call_doc :: forall f. Call (Call f) -> Doc
call_doc (Call Call f
call [Arg]
args) = Text -> Doc
Doc.Doc forall a b. (a -> b) -> a -> b
$ [Text] -> Text
Text.unwords forall a b. (a -> b) -> a -> b
$ Text
name forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Arg -> Text
arg_doc [Arg]
args
    where Derive.CallName Text
name = forall func. Call func -> CallName
Derive.call_name Call f
call

arg_doc :: Arg -> Text
arg_doc :: Arg -> Text
arg_doc (Given (Literal Val
val)) = forall a. ShowVal a => a -> Text
ShowVal.show_val Val
val
arg_doc (Given (ValCall ValCall
call [Arg]
args)) =
    Text
"(" forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
Text.unwords (Text
name forall a. a -> [a] -> [a]
: forall a b. (a -> b) -> [a] -> [b]
map Arg -> Text
arg_doc [Arg]
args) forall a. Semigroup a => a -> a -> a
<> Text
")"
    where Derive.CallName Text
name = ValCall -> CallName
Derive.vcall_name ValCall
call
arg_doc Arg
Var = Text
"$"