8

私はgeneralises($)のように一般化することを考えていましたが、この記事の最後にあるコード (また ideone ) でそれを実行しました。Control.Category(.)

このコードでは、 というクラスを作成しましたFunctionObject。このクラスには($)、次のシグネチャを持つ関数があります。

($) :: f a b -> a -> b

当然(->)、このクラスのインスタンスを作成するので$、通常の関数を引き続き使用できます。

ただし、これにより、たとえば、以下の例に示すように、独自の逆数を知っている特別な関数を作成できます。

私は、次の 3 つの可能性のうちの 1 つがあると結論付けました。

  1. 私はそれについて考えるのが最初です。
  2. 他の誰かがすでにそれを行っており、私は車輪を再発明しています.
  3. それは悪い考えです。

オプション 1 の可能性は低いと思われ、hayooでの検索ではオプション 2 が見つからなかったので、オプション 3 が最も可能性が高いと思われますが、誰かがその理由を説明できるなら、それは良いことです.

import Prelude hiding ((.), ($))
import Control.Category ((.), Category)

class FunctionObject f where
  ($) :: f a b -> a -> b

infixr 0 $

instance FunctionObject (->) where
  f $ x = f x

data InvertibleFunction a b = 
   InvertibleFunction (a -> b) (b -> a)

instance Category InvertibleFunction where
  (InvertibleFunction f f') . (InvertibleFunction g g') =
    InvertibleFunction (f . g) (g' . f')

instance FunctionObject InvertibleFunction where
  (InvertibleFunction f _) $ x = f $ x

inverse (InvertibleFunction f f') = InvertibleFunction f' f

add :: (Num n) => n -> InvertibleFunction n n
add n = InvertibleFunction (+n) (subtract n)

main = do
  print $ add 2 $ 5 -- 7
  print $ inverse (add 2) $ 5 -- 3
4

2 に答える 2