繁体   English   中英

不了解Haskell中的功能和值fmap

[英]Do Not Understand fmap of Function and Value in Haskell

我对此表达式的结果感到困惑:

fmap (*) 3

产生类型:

fmap (*) 3 :: (Functor f, Num a, Num (f a)) => f (a -> a)

我期望的是结果将与这样做相同:

(*) 3

产生一个1-参数的函数:

Prelude> (*) 3 $ 10
30

我期望fmap3应用于(*)产生(*3) ,但是以下产生错误:

Prelude> (fmap (*) 3) 10

<interactive>:201:1:
    Non type-variable argument in the constraint: Num (a -> a)
    (Use FlexibleContexts to permit this)
    When checking that `it' has the inferred type
      it :: forall a a1. (Num a, Num a1, Num (a1 -> a)) => a -> a

(fmap (*) 3)预期的结果是什么类型的参数?

关键在这里:

fmap (*) 3 :: (Functor f, Num a, Num (f a)) => f (a -> a)
                                 ^^^^^^^^^

在Haskell中,数字文字被重载,因此3可以具有任何类型b ,只要b具有Num实例即可。

编译器进行以下分析:

  1. 3具有某种类型的b与约束Num b
  2. fmap类型为Functor f => (a -> c) -> fa -> fc fmap Functor f => (a -> c) -> fa -> fc fmap Functor f => (a -> c) -> fa -> fc
  3. 所以*类型a -> c fa a -> c ,3的类型为fa
  4. *具有类型Num a => a -> a -> a so c = Num a a -> a ,并且a具有约束Num a
  5. b =(1)和(2)中的fa

收集所有约束和对等条件:

fmap (*) 3 :: ( Functor f,       -- by (2)
                Num a,           -- by (4)
                Num (f a)        -- by (1) and (5)
              ) => f ( a -> a )  -- by (2) and c = a -> a

更新:

您要求一个示例,其中fmap (*) 3有意义。 这里有问题的是(*)具有arity 2,并且fmap通常与单个参数(arity 1)一起使用。 例如:

fmap (+1) (Just 3)  = Just 4
fmap (+1) Nothing   = Nothing
fmap (*6) [1,2,3]   = [6,12,18]
fmap words getLine  = do x <- getLine; return (words x)

注意: (+1)只是“加1”函数,例如\\x -> x+1 ,而(*6)只是乘以6的函数,例如\\x -> x*6

因此,映射(*) :: Int -> Int -> Int Int- (*) :: Int -> Int -> Int Int- (*) :: Int -> Int -> Int有点不寻常。 当然,我们可以将(*)的类型解释为Int -> (Int -> Int) ,从而得到奇数1,但是处理函数的函子将进入我们通常不处理的抽象级别用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM