概括($),如Control.Category概括(。) [英] Generalising ($) like Control.Category generalises (.)

查看:118
本文介绍了概括($),如Control.Category概括(。)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经想过概括($),比如 Control.Category generalises ( 。),并且我已经在这篇文章的末尾使用了代码( ideone )。

在这段代码中,我创建了一个名为 FunctionObject 的类。这个类有一个函数($),其签名如下:

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

当然,我会让( - >)这个类的一个实例,所以 $ 可以继续使用普通函数。



但是这可以让你特别函数,例如,知道它们自己的逆函数,如下例所示。



我已经总结出以下三种可能性之一:


  1. 我是第一个想到它的人。 其他人已经完成了它并且我正在重新发明轮子。 / li>
  2. 这是一个糟糕的主意。

选项1看起来不太可能,我在 hayoo 没有透露选项2,所以我怀疑选项3是最有可能的,但如果有人能解释为什么那是

  import前导隐藏((。),($))
import Control.Category( (。),Category)

class FunctionObject f其中
($):: fab - > a - > b

infixr 0 $

实例FunctionObject( - >)其中
f $ x = fx

数据InvertibleFunction ab =
InvertibleFunction(a - > b)(b - > a)

实例类别InvertibleFunction其中
(InvertibleFunction f f')。 (InvertibleFunction g g')=
InvertibleFunction(f。g)(g'。f')

实例FunctionObject InvertibleFunction其中
(InvertibleFunction f _)$ x = f $ x

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

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

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


解决方案

在Haskell中用于这样的事物的抽象,一个使用箭头 s和另一个 Applicative s。两者都可以分解为比 base 中使用的部分更小的部分。






如果您进入箭头方向和箭头 s的功能分解为组成部分,您将有一个单独的类那些能够将任意函数提升到箭头中的箭头。

  class ArrowArr a where 
arr ::(b - > c) - > abc

这与 ArrowArr ,箭头可以将任意箭头放到函数中。

  class ArrowFun a where 
($):: abc - > (b - > c)

如果您只是将 arr 关闭箭头您只剩下类似箭头的箭头了并解构元组

  class Category a => ArrowLike a where 
fst :: a(b,d)b
snd :: a(d,b)b
(&&& amp;):: a b c - > a b c' - > ab(c,c')






如果你去在 Applicative 方向,这是 Copoint Applicative without pure (名称 申请 )。

  class Copoint p where Source 
copoint :: p a - > a

类Functor f =>应用f,其中
(<。>):: f(a - > b) - > f a - > fb

当您这样做时,您通常会放弃 Category 代替函数,而是有一个类型构造函数 C a ,它代表根据一组规则构造的值(包括函数值)。


I had a thought to generalise ($) like Control.Category generalises (.), and I've done so with the code at the end of this post (also ideone).

In this code I've created a class called FunctionObject. This class has a function ($) with the following signature:

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

Naturally I make (->) an instance of this class so $ continues to work with ordinary functions.

But this allows you to make special functions that, for example, know their own inverse, as the example below shows.

I've concluded there's one of three possibilities:

  1. I'm the first to think of it.
  2. Someone else has already done it and I'm reinventing the wheel.
  3. It's a bad idea.

Option 1 seems unlikely, and my searches on hayoo didn't reveal option 2, so I suspect option 3 is most likely, but if someone could explain why that is it would be good.

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

解决方案

There are two abstractions used for things like this in Haskell, one usings Arrows and the other Applicatives. Both can be broken down into smaller parts than those used in base.


If you go in the Arrow direction and break down the capabilities of Arrows into component pieces, you'd have a separate class for those arrows that are able to lift arbitrary functions into the arrow.

class ArrowArr a where
    arr :: (b -> c) -> a b c

This would be the opposite of ArrowArr, arrows where any arbitrary arrow can be dropped to a function.

class ArrowFun a where
    ($) :: a b c -> (b -> c)

If you just split arr off of Arrow you are left with arrow like categories that can construct and deconstruct tuples.

class Category a => ArrowLike a where
    fst   :: a (b, d) b
    snd   :: a (d, b) b
    (&&&) :: a b c -> a b c' -> a b (c,c')


If you go in the Applicative direction this is a Copointed "Applicative without pure" (which goes by the name Apply).

class Copointed p where Source
    copoint :: p a -> a

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

When you go this way you typically drop the Category for functions and instead have a type constructor C a representing values (including function values) constructed according to a certain set of rules.

这篇关于概括($),如Control.Category概括(。)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆