====== Record syntax ======
* algebraic sum type )1
* provides access functions
* fields in curly brackets, comma separated
* short example:
*
data MatrixCursor = MatrixCursor { rnRow :: Integer, rnCol :: Integer }
----
)1 An algebraic sum type (see also https://en.wikipedia.org/wiki/Algebraic_data_type regarding sum types) is a type with different constructors seperated by ''|''. Record syntax can generate errors, if combined with sum types.
===== Advantages=====
* can document the intended use of fields
* see example 1
* provides functions to get the records content
* see example 2
* example 1:
*
{-| to be able to print into a 'CharMatrix'
* prefix: xc
* instance of Formatting to print the stored characters
-}
data MatrixCursor =
MatrixCursor {
-- | the row, starting at 0
rnRow :: Integer,
-- | the column starting at 0
rnCol :: Integer }
deriving Show
* example 2:
*
print $ rnCol xc
===== Disadvantages=====
==== With sum types combined: risk of runtime errors ====
* example:
*
module Main where
main :: IO ()
main = do
print $ nDiameterInMM SomethingElse
data Wood = Log { nDiameterInMM :: Float, nLengthInMM :: Float } | SomethingElse
deriving Show
* output of runtime error:
*
Test2-exe.exe: No match in record selector nDiameterInMM
==== Risk of namespace colisions without strong coding rules ====
Fields from records can be extrated by the accessor functions that have been declared within the record. Alternatively, records can be extrated by pattern matching, as well. If you use both with the same name then the pattern matching will shadow the accessor function(s).
Risk can be completely excluded by compiling with ghc parameter -Wall and cleaning up all warnings.
Risk can be mitigated by [[codesnippets:codingconventions#record_syntax|Coding rules]].
* example 1:
*
module Main where
main :: IO ()
main = do
print $ nCol xcToPrint
{-| to be able to print into a 'CharMatrix'
* prefix: xc
* instance of Formatting to print the stored characters
-}
data MatrixCursor =
MatrixCursor {
-- | the row, starting at 0
nRow :: Integer,
-- | the column starting at 0
nCol :: Integer }
deriving Show
xcToPrint :: MatrixCursor
xcToPrint = incMatrixCursorCol 5 $ incMatrixCursorCol 2 $ incMatrixCursorCol 3 $ initMatrixCursor
incMatrixCursorCol :: Integer -> MatrixCursor -> MatrixCursor
incMatrixCursorCol n xc@(MatrixCursor _ nCol) = (MatrixCursor (nRow xc) (nCol+n))
initMatrixCursor :: MatrixCursor
initMatrixCursor = (MatrixCursor 0 0)
* compiler output (using ''stack ghc -- **-Wall** ./app/Main.hs''):
*
[1 of 1] Compiling Main ( app\Main.hs, app\Main.o )
app\Main.hs:24:45: warning: [-Wname-shadowing]
This binding for `nCol' shadows the existing binding
defined at app\Main.hs:17:13
|
24 | incMatrixCursorCol n xc@(MatrixCursor _ nCol) = (MatrixCursor (nRow xc) (nCol+n))
| ^^^^
Linking app\Main.exe ...
* example 2:
*
module Main where
main :: IO ()
main = do
print $ nCol xcToPrint
{-| to be able to print into a 'CharMatrix'
* prefix: xc
* instance of Formatting to print the stored characters
-}
data MatrixCursor =
MatrixCursor {
-- | the row, starting at 0
nRow :: Integer,
-- | the column starting at 0
nCol :: Integer }
deriving Show
xcToPrint :: MatrixCursor
xcToPrint = incMatrixCursorCol 5 $ incMatrixCursorCol 2 $ incMatrixCursorCol 3 $ initMatrixCursor
incMatrixCursorCol :: Integer -> MatrixCursor -> MatrixCursor
incMatrixCursorCol n xc@(MatrixCursor nRow nCol) = (MatrixCursor (nRow xc) (nCol+n))
initMatrixCursor :: MatrixCursor
initMatrixCursor = (MatrixCursor 0 0)
* compiler output:
*
[2 of 2] Compiling Main
app\Main.hs:24:71: error:
* Couldn't match expected type `MatrixCursor -> Integer'
with actual type `Integer'
* The function `nRow' is applied to one argument,
but its type `Integer' has none
In the first argument of `MatrixCursor', namely `(nRow xc)'
In the expression: (MatrixCursor (nRow xc) (nCol + n))
|
24 | incMatrixCursorCol n xc@(MatrixCursor nRow nCol) = (MatrixCursor (nRow xc) (nCol+n))
| ^^^^^^^
* example 3 (warning free with ''stack ghc -- **-Wall** ./app/Main.hs''):
*
module Main where
main :: IO ()
main = do
print $ rnCol xcToPrint
{-| to be able to print into a 'CharMatrix'
* prefix: xc
* instance of Formatting to print the stored characters
-}
data MatrixCursor =
MatrixCursor {
-- | the row, starting at 0
rnRow :: Integer,
-- | the column starting at 0
rnCol :: Integer }
deriving Show
xcToPrint :: MatrixCursor
xcToPrint = incMatrixCursorCol 5 $ incMatrixCursorCol 2 $ incMatrixCursorCol 3 $ initMatrixCursor
incMatrixCursorCol :: Integer -> MatrixCursor -> MatrixCursor
incMatrixCursorCol n xc@(MatrixCursor _ nCol) = (MatrixCursor (rnRow xc) (nCol+n))
initMatrixCursor :: MatrixCursor
initMatrixCursor = (MatrixCursor 0 0)
* output:
*
10
===== ✎ =====
~~DISCUSSION~~