Hacker News new | past | comments | ask | show | jobs | submit login
Functional architecture is Ports and Adapters (2016) (ploeh.dk)
77 points by mpweiher on Dec 28, 2017 | hide | past | favorite | 9 comments



Interestingly, if you rewrite the function with a more general type such as

    checkCapacity' :: forall f. Functor f => Int -> (ZonedTime -> f Int) -> Reservation -> f (Either Error Reservation)
you can guarantee that any effects in the final result only come from the function you supplied to it, i.e. checkCapacity' cannot add any effects of its own(Also, it can only "run" the function exactly once).

The type of the arguments of checkCapacity' are also a strict generalisation of the arguments to

    checkCapacity :: Int -> (ZonedTime -> IO Int) -> Reservation -> Either Error Reservation
meaning that any valid arguments to checkCapacity are valid for checkCapacity' as well.


I think you must mean

    checkCapacity :: Int -> (ZonedTime -> IO Int) -> Reservation -> IO (Either Error Reservation)


Interesting that the foray into Haskell led him to pass in a _value_ rather than a function ... which is exactly what "Functional Core, Imperative Shell" proposes.

(Functional Core, Imperative Shell is often linked with Hexagonal / Onion / Ports and Adapters. It is a bit more opinionated about using values as boundaries I believe ... and I think it is right).

EDIT: TFA is a good article, worth reading.


In my experience a good larger architecture is mostly OOP but where the implementations make good use of FP patterns like map and reduce instead of the equivalent loops.


functional core & imperative shell / haxagonal / onion / ports & adapters / DDD I really can't figure out the commonality of these metaphors


At it's core all of these things are pretty much new names and some constraints on existing architectural patterns like service/service interface (facade), layered design, and service agent/service. They tend to be a bit divisive in that traditional layers, for example (presentation/business/data) is seen as a constraint, and layers in onion have no constraint. Detractors of hexagonal architetcure suggest it implies no more than 6 ports and adaptors, and so on.

Ultimately none of these patterns matter. The design philosophy that underlies them (separation of concerns, for example) does. It's something that becomes self-evident as you progress from junior to senior and beyond. We as an industry seem to love telling each other how our way is the one true way.


My Haskell is a bit rusty, but I think the Haskell example could improve A LOT by using monad transformers or a free monad?


Wouldn't that make it harder to directly translate back to F# which is his goal?

I understood the only purpose of writing the Haskell was didactic, and to improve his F# code. It seems that moving further from constructs in F# would work against this.


I think that computation expressions would allow him to do the same in F#?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: