SwiftでFunctor型を書いてみる
Functorとは
構造内の値に関数を適用できるものである。
しかし、これだけを聞いてもわかりづらい。
この記事では、HaskellのFunctorを参考にSwiftのOptionalを用いてFunctorを理解していきたい。
HaskellのFunctor
class Functor f where fmap:: (a-> b) -> f a -> fb
Functor型は、一つの関数fmap
を持つクラスである。
f
は、aやbのような具体型ではなく、一つの型引数を受け取る型コンストラクタだ。
具体型 : 型引数を一つも取らない全ての型引数が埋まっている型
型コンストラクタは、一つの型引数を取って具体型になるもの。
型コンストラクタの例としてリストがあげられる。
リストは、[]
では具体型ではなく、[Int]となって具体型になるからだ。
つまり、fa -> fb
ということから、fという構造を持ったままa型 -> b型に関数を適用していることがわかる。
Swiftでの実装
Optionalも型コンストラクタなので、
SwiftのOptionalを使って、Functorの実装を行なっていくことにする。
まずは、Functor型を作っていく。
protocol Functor { associatedtype A associatedtype B associatedtype F func fmap(f: ((A) -> B)) -> F }
enum FunctorOptional<T>: Functor { typealias A = T typealias B = T typealias F = FunctorOptional case some(value: T) case none func fmap(f: ((A) -> B)) -> F{ switch self { case .some(let value): return .some(value: f(value)) case .none: return .none } } } let value = FunctorOptional.some(value: 1) let notValue = FunctorOptional<Int>.none print(value.fmap(f: { $0 + 2} )) print(notValue.fmap(f: { $0 + 2 })) //some(value: 3) //none
OptionalにもMapが用意されているため、実装に置いてのメリットは提示できないが、fmapを使っての実装を書くことができた。