通过函子和函数组合使用 Haskell 进行柯里化

pen*_*142 1 haskell currying

我有以下问题。我有一个功能很好用。

\n
getName :: Style -> Css -> Maybe String\ngetName s css = map intToChar .  intToBase 26 <$> getIndex s css\n
Run Code Online (Sandbox Code Playgroud)\n

我想知道为什么我不能这样定义它:

\n
getName :: Style -> Css -> Maybe String\ngetName = map intToChar .  intToBase 26 <$> getIndex\n
Run Code Online (Sandbox Code Playgroud)\n

我认为柯里化可以让我将其作为带有两个参数的函数返回,而不是作为具有两个参数的函数

\n

如果它有助于您的理解:

\n
intToChar :: Int -> Char\nintToBase :: Int -> Int -> [Int]\ngetIndex :: Style > Css -> Maybe Int\n
Run Code Online (Sandbox Code Playgroud)\n

啊,不要忘记错误:

\n
error:\n    \xe2\x80\xa2 Couldn't match type \xe2\x80\x98[a] -> Maybe Int\xe2\x80\x99 with \xe2\x80\x98Int\xe2\x80\x99\n      Expected type: a -> Int\n        Actual type: a -> [a] -> Maybe Int\n    \xe2\x80\xa2 Probable cause: \xe2\x80\x98getIndex\xe2\x80\x99 is applied to too few arguments\n      In the second argument of \xe2\x80\x98(<$>)\xe2\x80\x99, namely \xe2\x80\x98getIndex\xe2\x80\x99\n      In the expression: map intToChar . intToBase 26 <$> getIndex\n      In an equation for \xe2\x80\x98getName\xe2\x80\x99:\n          getName = map intToChar . intToBase 26 <$> getIndex\n    \xe2\x80\xa2 Relevant bindings include\n        getName :: a -> [Char] (bound at src/Css/Css.hs:17:1)\n   |        \n17 | getName = map intToChar .  intToBase 26 <$> getIndex \n   |                                             ^^^^^^^^\n
Run Code Online (Sandbox Code Playgroud)\n

che*_*ner 5

问题是scss不能通过eta 转换消除,因为它们单独用作getIndexnot的参数map intToChar . intToBase 26 <$> getIndex

为了实现无点,你必须使用函数组合。首先,使用fmapnot重写您的定义<$>(并将不相关的参数隐藏到fmap局部变量后面)。

getName s css = fmap f (getIndex s css)
    where f = map intToChar . intToBase 26
Run Code Online (Sandbox Code Playgroud)

现在更容易看出您需要使用函数组合来首先消除css

-- f1 (f2 x) == f1 . f2
-- f1 = fmap f
-- f2 = getIndex s
getName s = fmap f . (getIndex s)
    where f = map intToChar . intToBase 26
Run Code Online (Sandbox Code Playgroud)

进而s

-- f1 (f2 x) = f1 . f2
-- f1 = (fmap f .)
-- f2 = getIndex
getName = (fmap f . ) . getIndex
    where f = map intToChar . intToBase 26
Run Code Online (Sandbox Code Playgroud)