绑定值不是第一个参数

Ale*_*har 3 haskell currying

我有一个名为"人"的班级

Person :: String -> String -> Int -> Gender -> Person
Run Code Online (Sandbox Code Playgroud)

目标: 通过将性别分配给女性来制作更一般的人物版本,女性角色.

什么有效: 绑定前N个元素有效:

let personsWithNameAlice = Person "Alice"
let personsWithNameAliceMcGee = Person "Alice" "McGee"
Run Code Online (Sandbox Code Playgroud)

什么行不通:

let femalePerson = Person {gender = Female}
Run Code Online (Sandbox Code Playgroud)

题:

  • 我该怎么做呢?
  • 如何将值绑定到n!= 0的任何函数的第n个元素?

只是我知道我可以在数学中编写f(x,y,z)= g(x,y,z,5),在C++中编写std :: bind2nd(f,8)所以不应该在Haskell中编写?

Con*_*nal 13

使用语义编辑器组合器.例如,假设您有一个功能:

foo :: Int -> String -> Bool -> Char -> Float
foo = undefined
Run Code Online (Sandbox Code Playgroud)

我已经将示例更改为涉及所有不同类型,因此类型检查将确保我们的定义正确.我们需要以下四种特化,每种特殊化都来自填充一个参数:

foo0 ::        String -> Bool -> Char -> Float  -- 3
foo1 :: Int ->           Bool -> Char -> Float  -- "hey"
foo2 :: Int -> String ->         Char -> Float  -- True
foo3 :: Int -> String -> Bool ->         Float  -- 'x'
Run Code Online (Sandbox Code Playgroud)

第一个很容易,直接部分应用:

foo0 = foo 3
Run Code Online (Sandbox Code Playgroud)

但是,让我们以奇怪的方式写它(为了与其他人保持一致):

foo0 = ($ 3) foo
Run Code Online (Sandbox Code Playgroud)

对于其他人,使用result,这是组成的同义词:

result :: (b -> b') -> ((a -> b) -> (a -> b'))
result = (.)
Run Code Online (Sandbox Code Playgroud)

result将给定函数的目标应用于另一个函数的"结果"(因此直接类似于函数firstsecond函数Control.Arrow).然后重复的应用程序瞄准多个结果,跳过连续的curried参数,正如我们所需:

foo1 = result ($ "hey") foo
foo2 = (result.result) ($ True) foo
foo3 = (result.result.result) ($ 'x') foo
Run Code Online (Sandbox Code Playgroud)

请注意,第n个专业化使用result自身组合n次.


Dan*_*her 7

你可以用lambda表达式来实现

Person :: String -> String -> Int -> Gender -> Person
Run Code Online (Sandbox Code Playgroud)

你定义了

femalePerson = \fn ln a -> Person fn ln a Female
Run Code Online (Sandbox Code Playgroud)

或者,在绑定中使用参数:

femalePerson fn ln a = Person fn ln a Female
Run Code Online (Sandbox Code Playgroud)

如果要特定绑定第二个参数,flip则是您想要的功能

third = flip (/) 3
Run Code Online (Sandbox Code Playgroud)

您可以使用flip绑定任意位置的参数,但这很快变得麻烦且难以理解:

femalePerson = curry . curry $ flip (uncurry (uncurry Person)) Female
Run Code Online (Sandbox Code Playgroud)