是否有可能使这个递归函数无点?

Mat*_*att 1 haskell

我有一个简单的功能,并希望有点无意义的风格.

shout :: String -> String
shout input
  | null input = []
  | otherwise = (toUpper . head $ input) : (shout . tail $ input)
Run Code Online (Sandbox Code Playgroud)

我的直觉引领着我

pfShout :: String -> String
pfShout = (toUpper . head) : (shout . tail)
Run Code Online (Sandbox Code Playgroud)

这是对cons细胞的第一个论点的抱怨

无法将预期类型'String - > String'与实际类型'[[Char] - > Char]'匹配

  • 可能的原因:'(:)'适用于太多参数

    在表达式中:( toUpper.head):( pfShout.tr尾)

    在'pfShout'的等式中:pfShout =(toUpper.head):( pfShout.tr尾)

并且抱怨cons细胞的第二个论点

无法将预期类型'[[Char] - > Char]'与实际类型'[Char] - > String'匹配

  • 可能原因:'(.)'适用于太少的参数

    在'(:)'的第二个参数中,即'(pfShout.tr尾)'

    在表达式中:( toUpper.head):( pfShout.tr尾)

    在'pfShout'的等式中:pfShout =(toUpper.head):( pfShout.tr尾)

我很清楚,我无法列出'String - > String'函数和 '[[Char] - > Char]'的列表,而且我开始找到一个我想到的地方只是不会无点工作.

我知道这里有其他的考虑因素(比如现在我错过了一个基础案例),但是.我也明白我可以完全重写函数来达到同样的效果(比如map toUpper).我主要感兴趣的是在编写函数时使用递归函数进行递归.

如果可以(或不可能)无点地编写此功能,我缺少什么?

jpa*_*ath 7

正如@nm所说,你可以使用shout = map toUpper.然而,没有map或任何其他花哨的功能可以做到这一点foldr,但我们需要更多的组合器.我们需要的东西,需要我们的输入参数,并将其传递给两个函数toUpper . head和shout . tail,然后将它们组合使用:.你可能还不知道这个功能,但<*>来自applicative 的操作员有我们需要的东西:

(f <*> g) x = f x (g x)
Run Code Online (Sandbox Code Playgroud)

现在我们可以这样做:

combine . f <*> g = \x -> combine (f x) (g x) -- [1]
Run Code Online (Sandbox Code Playgroud)

我会让你弄清楚如何将这个应用到你的问题中.;)

但我们仍然需要以某种方式表达空列表案例.有多种方法可以做到这一点,但最简单的方法是boolfrom Data.Bool函数,它就像一个if函数,以及joinfrom Control.Monad.

-- [2]
bool x _ False = x
bool _ x True  = x

join f x = f x x
Run Code Online (Sandbox Code Playgroud)

现在我们可以做到以下几点:

shout = join $ bool (not null case) (null case) . null
-- Which translates to
shout xs = bool ((not null case) xs) ((null case) xs) (null xs)
Run Code Online (Sandbox Code Playgroud)

再次实施这两个案例留给读者作为练习.

[1]:而不是(.)你也可以使用(<$>)哪个功能是相同的(.)但是(<$>)和它们(<*>)属于一起.一旦你了解了应用程序,你就会明白为什么.

[2]:如果你想知道参数顺序背后的原因bool是什么,第一个参数就是这种False情况因为Bool定义如下:

data Bool = False | True
Run Code Online (Sandbox Code Playgroud)

这个命令的动机来自于这个惯例False < True.maybe并且either是与其共享这种确切模式的另外两个函数bool.