Prelude モジュールを読む (2) Data.Void, Control.Category, Control.Apply, Control.Semigroupoid

Prelude モジュールを読む (2) Data.Void, Control.Category, Control.Apply, Control.Semigroupoid

Prelude モジュールは purescript-prelude パッケージで定義されているモジュールです。

今回は以下の4つのモジュールを確認します。

  • Data.Void
  • Control.Semigroupoid
  • Control.Category
  • Control.Apply

Data.Void

PureScript Haskell
Void Data.Void.Void
absurd Data.Void.absurd

Void

値を持たない型ですね。

newtype Void = Void Void  

absurd

absurd :: forall a. Void -> a  
absurd a = spin a  
  where  
  spin (Void b) = spin b  

Haskellの実装とは少し違いますね。

absurd :: Void -> a  
absurd a = case a of {}  

Control.Semigroupoid

Haskellには存在しない型クラスです。
HaskellCategory型クラスのid(.)を分離した感じですね。

PureScript Haskell
Semigroupoid 型クラス -
compose, (<<<) (.)

Semigroupoid

class Semigroupoid a where  
  compose :: forall b c d. a c d -> a b c -> a b d  

compose, (<<<)

instance semigroupoidFn :: Semigroupoid (->) where  
  compose f g x = f (g x)  

infixr 9 compose as <<<  

Haskellでは(.)として定義されています。
この演算子の変更はレコード構文との兼ね合いでしょうね。たぶん。

Control.Category

PureScript Haskell
Category 型クラス Control.Category.Category
identity id

Category

class Semigroupoid a <= Category a where  
  identity :: forall t. a t t  

identity

instance categoryFn :: Category (->) where  
  identity x = x  

PureScriptにはidが無い・・・。
その代わりidentityがあります。確かにDOM操作する時とかidって名前だと、とても使いづらいので良いかも。

Control.Apply

これはHaskellには無いですね。FunctorApplicativeの間の型クラスのようです。pure<*>を分離したってことですかね。

PureScript Haskell
Apply 型クラス -
apply, <*> <*>
(<*) (<*)
(*>) (*>)

Apply

Formally, Apply represents a strong lax semi-monoidal endofunctor.

class Functor f <= Apply f where  
  apply :: forall a b. f (a -> b) -> f a -> f b  

infixl 4 apply as <*>  

型クラス制約はHaskellと逆向きの太っちょ矢印なんですね。Super classes #162に理由が載ってる。=>を含意 (ならば) として読むとすると、確かにそうかも。

(<*)

applyFirst :: forall a b f. Apply f => f a -> f b -> f a  
applyFirst a b = const <$> a <*> b  

infixl 4 applyFirst as <*  

(*>)

applySecond :: forall a b f. Apply f => f a -> f b -> f b  
applySecond a b = const identity <$> a <*> b  

infixl 4 applySecond as *>  

const identity :: a -> b -> b を使ってますね。僕の好きな部分適用の1つです。

感想

HaskellよりHaskellらしいの意味が少しわかってきました。

進捗

  • Control.Applicative
  • Control.Apply
  • Control.Bind
  • Control.Category
  • Control.Monad
  • Control.Semigroupoid
  • Data.Boolean
  • Data.BooleanAlgebra
  • Data.Bounded
  • Data.CommutativeRing
  • Data.DivisionRing
  • Data.Eq
  • Data.EuclideanRing
  • Data.Field
  • Data.Function
  • Data.Functor
  • Data.HeytingAlgebra
  • Data.Monoid
  • Data.NaturalTransformation
  • Data.Ord
  • Data.Ordering
  • Data.Ring
  • Data.Semigroup
  • Data.Semiring
  • Data.Show
  • Data.Unit
  • Data.Void