繁体   English   中英

如何将泛型函数作为参数传递给另一个函数?

[英]How to pass a generic function as parameter to another function?

假设我有三个功能:

data Foo = Foo { x :: String, y :: String, z:: String }

fooZero :: Foo
fooZero = Foo "empty" "empty" "empty"

fooOne :: String -> Foo
fooOne a = Foo a "empty" "empty"

fooThree :: String -> String -> String -> Foo
fooThree a b c = Foo (doSomething a) (doSomethingElse b) (doAnotherThing c)

现在,我希望能够在另一个函数中传递它们( f :: (???? -> Foo) ,仅在另一个昂贵的函数( evalSomething )需要它的情况下才执行:

bar :: Int -> Int -> (???? -> Foo) -> Int
bar a b f = if (a == b) then a
            else if (a > b) then evalSomething f -- return Int
            else a + b

通过这种方式:

let one = "One"
let two = "Two"
let three = "Three"

bar 8 8 (fooZero)
bar 1 2 (fooOne one)
bar 5 3 (fooThree one two three)

我怎样才能做到这一点?

正如nm在评论中所说,您根本就不需要任何函数类型 –一阶类型bar :: Int -> Int -> Foo -> Int可以很好地完成工作,因为您不需要实际上为foo函数提供bar任何参数-这些参数在应用bar之前传递,即,您仅传递结果。 由于懒惰,因此foo函数是否昂贵并不重要,因此您宁愿不对它们进行评估,如果不需要的话:Haskell将确保如果您实际上不需要它们,就不会评估函数结果!

一般来说, 一种东西,可以让你“通过泛型函数作为参数”虽然。 这称为Rank-2多态性

{-# LANGUAGE Rank2Types    #-}
{-# LANGUAGE UnicodeSyntax #-}

bar :: Int -> Int -> (∀ t . Monoid t => t -> Foo) -> Int
bar a b f
  | a == b     = a
  | a > b      = f (mempty :: [])
  | otherwise  = a + b

(如果你不是Unicode语法的球迷,你也可以写forall 。)实际上并不似乎是你想要的应用程序,但。

只需声明为:

bar :: Int -> Int -> Foo -> Int
bar a b f = if (a == b) then a
        else if (a > b) then evalSomething f
        else a + b

并将其称为:

bar 5 3 (fooThree one two three)

由于Haskell是惰性的,除非在evalSomething中需要fooThree,否则实际上不会对其进行评估。

暂无
暂无

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

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