Comment on Golang be like
Nevoic@lemmy.world 1 year agoHere’s an example (first in Haskell then in Go), lets say you have some types/functions:
- type Possible a = Either String a
- data User = User { name :: String, age :: Int }
- validateName :: String -> Possible String
- validateAge :: Int -> Possible Int
then you can make:
mkValidUser :: String -> Int -> Possible User mkValidUser name age = do validatedName <- validateName name validatedAge <- validateAge age pure $ User validatedName validatedAge
in Go you’d have these
- (no
Possible
type alias, Go can’t do generic type aliases yet, there’s an open issue for it) - type User struct { Name string; Age int }
- func validateName(name string) (string, error)
- func validateAge(age int) (int, error)
and with them you’d make:
func mkValidUser(name string, age int) (*User, error) { validatedName, err = validateName(name) if err != nil { return err } validatedAge, err = validateAge(age) if err != nil { return err } return User(Name: validatedName, Age: validatedAge) }
In the Haskell, the fact that Either
is a monad is saving you from a lot of boilerplate. You don’t have to explicitly handle the Left
/error case, if any of the Either
s end up being a Left
value then it’ll correctly “short-circuit” and the function will evaluate to that Left
value.
Without using the fact that it’s a functor/monad (e.g you have no access to fmap/>>=/do syntax), you’d end up with code that has a similar amount of boilerplate to the Go code (notice we have to handle each Left
case now):
mkValidUser :: String -> Int -> Possible User mkValidUser name age = case (validatedName name, validateAge age) of (Left nameErr, _) => Left nameErr (_, Left ageErr) => Left ageErr (Right validatedName, Right validatedAge) => Right $ User validatedName validatedAge