|
|
|
|
|
by Iceland_jack
1465 days ago
|
|
Instead of defining append_ for structure newtype Structure = Structure String
append_ :: Structure -> Structure -> Structure
append_ (Structure c1) (Structure c2) = Structure (c1 <> c2)
empty_ :: Structure
empty_ = Structure ""
the <> operator (from Semigroup) can be reused by deriving it via the underlying String type (edit: I see this is suggested later in the tutorial). {-# Language DerivingStrategies #-}
{-# Language GeneralizedNewtypeDeriving #-}
newtype Structure = Structure String
deriving
newtype (Semigroup, Monoid)
append_ :: Structure -> Structure -> Structure
append_ = (<>)
empty_ :: Structure
empty_ = mempty
Semigroup and Monoid let us use a lot of standard vocabulary concatStructure :: [Structure] -> Structure
concatStructure list =
case list of
[] -> empty_
x : xs -> x <> concatStructure xs
becomes concatStructure :: [Structure] -> Structure
concatStructure = mconcat
or concatStructure = fold
Also in the detour about kinds they are written as * while the ecosystem is moving towards a more uniform Type name. {-# Language StandaloneKindSignatures #-}
import Data.Kind (Type)
type Tuple :: Type -> Type -> Type
data Tuple a b = Tuple a b
type Either :: Type -> Type -> Type
data Either a b = Left a | Right b
|
|
Also, I'll update the text about kinds when GHC will use Type instead of * everywhere:
$ ghci
GHCi, version 9.2.2: https://www.haskell.org/ghc/ :? for help
λ> :k (,)
(,) :: * -> * -> *