Struct Embedding in Haskell
In Haskell, we can achieve a similar structure using algebraic data types and type classes. Here’s how we can translate the concept of struct embedding:
{-# LANGUAGE RecordWildCards #-}
import Text.Printf (printf)
data Base = Base
{ num :: Int
}
class Describer a where
describe :: a -> String
instance Describer Base where
describe Base{..} = printf "base with num=%d" num
-- A Container type that includes a Base
data Container = Container
{ base :: Base
, str :: String
}
-- Make Container an instance of Describer
instance Describer Container where
describe Container{..} = describe base
main :: IO ()
main = do
-- Create a Container with an embedded Base
let co = Container
{ base = Base { num = 1 }
, str = "some name"
}
-- Access fields directly
printf "co={num: %d, str: %s}\n" (num $ base co) (str co)
-- Access using the full path
putStrLn $ "also num: " ++ show (num $ base co)
-- Call the describe method on Container
putStrLn $ "describe: " ++ describe co
-- Demonstrate that Container implements Describer
let d :: Describer a => a
d = co
putStrLn $ "describer: " ++ describe d
In this Haskell version:
We define a
Base
data type with anum
field, similar to the Go struct.We create a
Describer
type class, which is analogous to the Go interface.We make
Base
an instance ofDescriber
, implementing thedescribe
method.We define a
Container
data type that includes aBase
and an additionalstr
field. This is similar to embedding in Go.We make
Container
an instance ofDescriber
by delegating to theBase
implementation.In the
main
function, we create aContainer
, access its fields, and demonstrate that it implements theDescriber
interface.
While Haskell doesn’t have struct embedding in the same way as Go, we can achieve similar functionality through composition and type classes. The RecordWildCards
language extension is used to make field access more convenient.
To run this program, save it as struct_embedding.hs
and use:
$ ghc struct_embedding.hs
$ ./struct_embedding
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1
This example demonstrates how Haskell can model similar concepts to Go’s struct embedding using its own idioms and features.