I'm trying to figure out what @
does in an expression like endpoint @"start"
. Is it part of a language extension perhaps?
I see the follow extensions enabled for the module the function is in.
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
The full function:
endpoints :: Contract () AuctionSchema Text ()
endpoints = (start' `select` bid' `select` close') >> endpoints
where
start' = endpoint @"start" >>= start
bid' = endpoint @"bid" >>= bid
close' = endpoint @"close" >>= close
The @ Symbol is used to both give a name to a parameter and match that parameter against a pattern that follows the @ . It's not specific to lists and can also be used with other data structures.
Essentially, a >> b can be read like "do a then do b , and return the result of b ". It's similar to the more common bind operator >>= .
Function Application Has Precedence over Operators In particular the $ operator has precedence 0; and the dot, function composition, has precedence 9. Parentheses may always be used to clarify both precedence and associativity.
It's merely an infix synonym for fmap , so you can write e.g. Prelude> (*2) <$> [1.. 3] [2,4,6] Prelude> show <$> Just 11 Just "11" Like most infix functions, it is not built-in syntax, just a function definition. But functors are such a fundamental tool that <$> is found pretty much everywhere.
There are two relevant extensions' documentation to read: TypeApplications
and DataKinds
. A snippet from the type applications documentation:
The
TypeApplications
extension allows you to use visible type application in expressions. Here is an example:show (read @Int "5")
. The@Int
is the visible type application; it specifies the value of the type variable inread
's type.
And from the data kinds documentation:
With
DataKinds
, GHC automatically promotes every datatype to be a kind and its (value) constructors to be type constructors.
I guess you sort of also have to know about Symbol
, a type-level representation of strings that is more efficient (but less featureful) than type-level [Char]
, but I couldn't find a good place in the official documentation to read about it. You can read about it some in the GHC.TypeLits
haddocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With