I am looking for a better alternative to the standard records which are just auto generated accessor functions over tuples. The problem is the naming issues where records with the same names of their fields get same accessor functions.
So in this article, we will be discussing eight Haskell alternative programming languages in a short brief. Some of the Haskell alternatives which we will be discussing are Java, Lua, Dart, Scala, Kotlin, Haxe, Nim, Asp.net, etc.
Haskell is fully cum purely functional computer programming language which is a bit lazy and polymorphically statically typed. The main part is that it is purely different from other programming languages in wide aspects.
In this example, two record accessors are defined, age and name, which allow us to access the age and name fields respectively. Record accessors are just Haskell functions which are automatically generated by the compiler. As such, they are used like ordinary Haskell functions.
The type system is too complicated yet still less powerful than Haskell's. Scala offers type inference, which, while giving the same safety as Java's type system, allows programmers to focus on the code itself, rather than on updating type annotations. Aside from Java itself, Scala is by far the most popular of the many JVM languages.
I am using lens with the makeFields TH function. This lets me do something like this:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data Person = Person { _personFirstName :: String
, _personLastName :: String
, _personEmail :: String }
data Corp = Corp { _corpName :: String
, _corpEmail :: String }
makeFields ''Person
makeFields ''Corp
main =
let myGuy = Person "Test" "Guy" "[email protected]"
myCorp = Corp "ABC" "[email protected]" in
putStrLn $ "personal email: " ++ (myGuy^.email) ++
"corp email: " ++ (myCorp^.email)
What is happening here is that the makeFields function creates type-classes HasName and HasEmail that have a single member (name, or email). It also creates instances for them for these types. MultiParamTypeClasses and Functional Dependencies make it possible to "overload" these members for different data types.
makeFields by convention is going to do this for each record constructor that begins with an underscore, and the name it will choose for the field is the balance of the constructor name beginning at the first capital letter. So _corpEmail makes an "email" field.
Now these "fields" are lenses, and there are a lot of functions that you can apply with them. To simply get the value from a record you could use the "view" function, e.g.:
view email myGuy
There is an inverse of this function called (^.), which takes a record as the first parameter and the lens as the second. I personally prefer this style in many cases but I still use view sometimes as well, particularly in a points-free style.
Lens is a LOT bigger than just this feature - I personally find this feature compelling but really the most important thing it does for you is enabling you to compose these lenses to make updates deep in data structures. Composition is simply with the (.) operator like any other function; so if we imagine my example had a _corpPresident :: Person
field, I could do this:
putStrLn $ myCorp^.president.email
Or - to change this nested value :
let newCorp = set president.email "[email protected]" myCorp
Or same thing (with more operator madness) :
let newCorp = myCorp & president.email .~ "[email protected]"
There is a lot more and I've hardly scratched the surface myself. The hackage docs are good but I think the best way to get started is with the field guide which is in the readme of the Github repository.
My policy for namespace conflicts is to put conflicting types in separate modules. Then you can use Haskell's namespacing tools to resolve conflicts. However, I wish Haskell had a way to define multiple namespaces within a single module.
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