Minor question/comment regarding the implementation of Result.map: Why do you create a new Result in the error case? Result is immutable (or am I missing something specific to Swift here?), so the old and new Result are the same and stay that way.
I'm not familiar with the internals of Swift, but e.g. in Scala, there is only one "None". If you call map or flatMap on it, the same None will always be returned.
flatMap :: Either e a -> (a -> Either e b) -> Either e b
flatMap x f =
case x of
Left _ -> x
Right x' -> f x'
In the case expression, you have to write `Left err -> Left err`, because `x` here has the type `Either e a`, but `Either e b` is expected. func map<U>(f: T -> U) -> Result<U> {
switch self {
case let .Value(value):
return Result<U>.Value(Box(f(value.unbox)))
case let .Error(error):
// self is Result<T>, but the return type must be Result<U>
return self
}
}Objects (of classes) are reference types so if Result was a class there would be a difference between returning self and returning a new Result.
Yeah, this is correct. This would be wrong:
func map<U>(f: T -> U) -> Result<U> {
switch self {
case let .Value(value):
return Result<U>.Value(Box(f(value.unbox)))
case let .Error(error):
// self is Result<T>, but the return type must be Result<U>
return self
}
}
As for efficiency: like you mention, enum are value types. For this reason, they're passed by copy! So even returning self would return a copy of self, not the same instance :)There are just a few tiny pieces missing from the puzzle: the functor and monad laws. They're pretty straight-forward - one would think they're common sense.
For functor, there is the mapping with identity law:
functor.map({ $0 }) == functor
which says that mapping the identity function over a functor results with a value equal to the one we started with
and the law for compositionality
functor.map({ f2(f1($0)) }) == functor.map(f1).map(f2)
which states that mapping a composite function yields the same result as mapping the first function then mapping the second function onto the result of the first map.
For monad, there are 3 additional laws (left identity, right identity and associativity).
I think that would make for another interesting article. I purposely ignored those details to make sure I kept my article more practical and less academic :) I also didn't mention the unit function of Monads (is that equivalent to one of the laws that you refer to?)
For those that are struggling with understanding (or feeling like you understand) monads, here are some articles like this one that I found very useful (note that the links are for haskell, but obviously, monads are a generally applicable concept).
A visual explanation of monads:
http://adit.io/posts/2013-04-17-functors,_applicatives,_and_...
The chapters on Functors, Applicatives, and Monoids that leads up to the chapter on monads (read the functors, applicatives, and monoids chapter first THEN the monad chatper and things will start to make sense):
http://learnyouahaskell.com/functors-applicative-functors-an...
[0] http://blog.sigfpe.com/2006/08/you-could-have-invented-monad...
In ocaml, a functor is a module that takes another module as a parameter. In this, a functor is a type that implements the map method. Is there something I'm missing that explains how both of them are functors?
I found this question on Stackoverflow.
http://stackoverflow.com/questions/16353066/how-are-functors...
func f()->Bool {
return true
}
func f()->Int {
return 5
}
let i:Int = f()
let b:Bool = f()
println(i) // Prints 5
println(b) // Prints true
// This would be compile error as ambiguous
//println(f())http://www.h4labs.com/dev/ios/swift.html?q=functional&age=10...