【问题标题】:Understanding foldr's definition理解foldr的定义
【发布时间】:2019-08-07 18:14:15
【问题描述】:

foldr的定义是(根据https://hackage.haskell.org/package/base-4.12.0.0/docs/src/GHC.Base.html#local-6989586621679020249

foldr            :: (a -> b -> b) -> b -> [a] -> b

这意味着第一个参数的类型是(a -> b -> b),第二个是b,第三个是[a],并返回b

如果我们看一个例子:

foldr (-) 54 [10, 11]

- 不接受两个相同类型,并返回相同类型吗?所以不应该是(a -> a -> a)吗?

【问题讨论】:

  • a -> a -> aa -> b -> b 的“特定”案例。
  • @WillemVanOnsem - 有时可以减去两种不同的类型吗?它不能用一个列表减去一个整数吗?
  • 不,(-) 函数在Num 类型类中定义为Num a => a -> a -> a。您可以使用 fromIntegral 之类的函数将一种数字类型转换为另一种类型。
  • 注意(-)的类型限制了foldr的结果类型:foldr :: (a -> b -> b) -> b -> [a] -> b,但是foldr (-) :: Num a => a -> [a] -> a,而不是b -> [a] -> b
  • 也许只是ab 是不同类型的示例:let f = foldr (\x y-> if (fst x > 0) then y else (y + snd x)) 0 处理元组列表并返回第一个参数大于零的所有第二个参数的总和。例如。 f [(1,2), ((-1),4), (3,2)] = 4.

标签: haskell


【解决方案1】:

函数的签名是a -> b -> b这一事实意味着ab应该是不同的类型。这意味着ab 可以是不同的类型。

例如,如果你使用(-) :: Num c => c -> c -> c,那么 Haskell 会推断:

foldr ::          (a -> b -> b) -> (b -> ([a] -> b))
(-)      Num c =>  c -> c -> c
----------------------------------------------------
a ~ c, b ~ c

所以abc 因此在这里是相同的类型。 foldr (-) 的类型因此具有类型:

foldr (-) :: Num c => c -> ([c] -> c)

foldr (-) 因此采用c 类型的数字,并返回一个将cs 列表映射到c 的函数。

【讨论】:

    【解决方案2】:

    我喜欢用这样的术语来解释这个主题:

    f :: a -> b -> b
    f x y = y 
    

    完全正确,ab 可能不同,并且有不同的类型,但它并没有说它不能是同一类型,所以:

    v = f 'c' True
    v :: Bool
    

    这里,f :: Char -> Bool -> Bool 但你也可以这样做:

    v2 = f False True
    v3 = f False False
    
    v2 :: Bool
    v3 :: Bool
    

    这里是f :: Bool -> Bool -> Bool

    不同的是当你希望这两个是同一类型并限制它们时,例如:

    sameTypeTuple :: a -> a -> (a,a)
    sameTypeTuple x y = (x,y)
    

    您将参数限制为同一类型:

    v4 = sameTypeTuple 'a' 'b'
    v4 :: (Char, Char)
    

    但是

    v5 = sameTypeTuple 'c' True
    

    会给你的

     error:
        • Couldn't match expected type ‘Char’ with actual type ‘Bool’
        • In the second argument of ‘sameTypeTuple’, namely ‘True’
          In the expression: sameTypeTuple 'c' True
          In an equation for ‘it’: it = sameTypeTuple 'c' True
    

    最后:

    foldr (-) 54 [10, 11] 你说ab 将是Num a0 => a0) 类型a0(类型是a0 而不是NumNum 是约束,类型类)

    【讨论】:

      猜你喜欢
      • 2019-04-03
      • 2016-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多