Haskell: Constraining function template variables with |
While I was browsing the persistent source, I found this function below in the Quasi.hs file (I mentioned the tag with the corresponding code equal to the one in the current state in the master branch, since the tag code is unlikely to change). The string takeConstraint ps tableName defs (n:rest) | not (T.null n) && isUpper (T.head n) = takeConstraint'
has this () character after the argument pattern. Is the expression between |
and =
how to limit the arguments in the template? So I interpret this |
as the same character in Math, that is, "such that"?
takeConstraint :: PersistSettings
-> Text
-> [FieldDef]
-> [Text]
-> (Maybe FieldDef, Maybe CompositeDef, Maybe UniqueDef, Maybe UnboundForeignDef)
takeConstraint ps tableName defs (n:rest) | not (T.null n) && isUpper (T.head n) = takeConstraint' --- <<<<< This line
where
takeConstraint'
| n == "Unique" = (Nothing, Nothing, Just $ takeUniq ps tableName defs rest, Nothing)
| n == "Foreign" = (Nothing, Nothing, Nothing, Just $ takeForeign ps tableName defs rest)
| n == "Primary" = (Nothing, Just $ takeComposite defs rest, Nothing, Nothing)
| n == "Id" = (Just $ takeId ps tableName (n:rest), Nothing, Nothing, Nothing)
| otherwise = (Nothing, Nothing, Just $ takeUniq ps "" defs (n:rest), Nothing) -- retain compatibility with original unique constraint
takeConstraint _ _ _ _ = (Nothing, Nothing, Nothing, Nothing)
source to share
Yes, that means exactly "such that". These are guards , very common in Haskell (an equivalent expression is usually preferred if
then
else
).
f x
| x > 2 = a
| x < -4 = b
| otherwise = x
equivalent to
f x = if x > 2 then a
else if x < -4 then b
else x
IMO that a concrete example would actually be better written neither with if
nor with protection, but
takeConstraint' = case n of
"Unique" -> (Nothing, Nothing, Just $ takeUniq ps tableName defs rest, Nothing)
"Foreign" -> (Nothing, Nothing, Nothing, Just $ takeForeign ps tableName defs rest)
"Primary" -> (Nothing, Just $ takeComposite defs rest, Nothing, Nothing)
"Id" -> (Just $ takeId ps tableName (n:rest), Nothing, Nothing, Nothing)
_ -> (Nothing, Nothing, Just $ takeUniq ps "" defs (n:rest), Nothing)
source to share