当前位置: 首页 > 知识库问答 >
问题:

在Haskell中部分应用函数类型(a->)作为函数实例

史昱
2023-03-14
instance Functor ((->) a) where
  fmap = TODO
instance Functor ((->) a) where
  fmap = (.)

我想出了这两个:

main = do
    putStrLn . show $ (fmap (+1) (*2)) (5 :: Int)
    putStrLn . show $ (fmap (show) (+1)) 3

我的例子正确地说明了这个练习吗?

fmap给定两个参数:

    null
    null

我在SO上看到了一些类似的问题(比如,这个问题),这个问题几乎是我要找的,但不完全是(我只是在找函数的例子,没有别的--没有应用性,没有单子)。

共有1个答案

贺皓
2023-03-14

对于函数ffmap的实现(对于任何可能的f,已知最多只有一个实现)必须具有(a->b)->f a->f b类型,并满足以下两个函数定律:

fmap id = id
fmap (g . h) = fmap g . fmap h

f是类型构造函数(->)r时,即f a表示r->a时,所需的类型签名是:

(a -> b) -> (r -> a) -> (r -> b)

(最后一对圆括号是不必要的,但我把它们留在里面,因为这样可以更容易看到“模式”),很容易看到的是(.)运算符的签名。

至于这两个定律,很明显,当你写下它们所说的话时,它们必须成立。我将通过煞费苦心地详细写出一切来证明它们:

fmap id = (.) id
        = \g -> id . g
        = \g -> (\a -> id (g a))
        = \g -> (\a -> g a)
        = \g -> g
        = id

fmap (g . h) = (.) (g . h)
             = \g1 -> (g . h) . g1
             = \g1 -> \a -> ((g . h) . g1) a
             = \g1 -> \a -> g (h (g1 a))

(fmap g) . (fmap h) = ((.) g) . ((.) h)
                    = \g1 -> ((.) g) (h . g1)
                    = \g1 -> g . h . g1
                    = \g1 -> \a -> g (h (g1 a))

所以那些也是一样的。

 类似资料:
  • 我现在在学习哈斯克尔。但我正在为“类型”而挣扎。 例如,函数的类型是

  • 我想封装我的,因此它被称为:。但是,我似乎无法正确获取类型/语法。我如何重新编写函数定义以实现这一目标?

  • 函数在Haskell中起主要作用,因为Haskell是一种函数式编程语言。与其他语言一样,Haskell确实具有自己的函数定义和声明。 函数声明由函数名称,其参数列表以及其输出组成。函数定义是实际定义函数的地方。让我们看看一个添加函数的示例,以详细了解此概念。 在这里,在第一行中声明了函数,在第二行中,我们编写了实际的函数,该函数将带有两个参数并产生一个整数类型的输出。 与大多数其他语言一样,Ha

  • @ganeshsittampalam在下面的一条评论中提出了一个重要的观点。我正在寻找“一个中途之家之间没有类型签名在所有和必须给一个精确的”。所以,我不是在寻找一个基于类型类的答案,我只是想让GHC为我的函数的未指定(或未完全限制)类型填充空白处。 是的,像这样的... ...可以工作,但仅限于参数,且函数不是无点的。是否有一种方法可以将这种技术应用于无点函数或返回值? @Rhymoid,如果你

  • 当涉及到将类别理论应用于泛型编程时,Haskell做得非常好,例如这样的库。但是,我不确定的一点是如何为多态类型创建泛型函数实例。 如果您有一个多态类型,比如列表或树,您可以创建一个from(Hask×Hask)到Hask的函数来表示它们。例如: 我试图找出是否有一种方法可以使这些类型(固定点)成为的一个通用实例,但我不确定如何实现。到目前为止,我遇到了以下两个问题: 1)首先,必须有一种方法来定

  • 作为一个Haskell新手,我不明白为什么表达式抛出异常和函数组合必须与运算符一起应用-它右边的表达式不需要进一步计算,因为它只是一个。编译它的另一种方法是将在括号中,但是与,那么为什么把它放在括号中可以编译表达式呢?