我有以下问题。我有一个功能很好用。
\ngetName :: Style -> Css -> Maybe String\ngetName s css = map intToChar . intToBase 26 <$> getIndex s css\nRun Code Online (Sandbox Code Playgroud)\n我想知道为什么我不能这样定义它:
\ngetName :: Style -> Css -> Maybe String\ngetName = map intToChar . intToBase 26 <$> getIndex\nRun Code Online (Sandbox Code Playgroud)\n我认为柯里化可以让我将其作为带有两个参数的函数返回,而不是作为具有两个参数的函数
\n如果它有助于您的理解:
\nintToChar :: Int -> Char\nintToBase :: Int -> Int -> [Int]\ngetIndex :: Style > Css -> Maybe Int\nRun Code Online (Sandbox Code Playgroud)\n啊,不要忘记错误:
\nerror:\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 | ^^^^^^^^\nRun Code Online (Sandbox Code Playgroud)\n
问题是s和css不能通过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)