Pet*_*all 17 haskell functor applicative
isAlphaNum :: Char -> Bool
isAlphaNum = (||) <$> isAlpha <*> isNum
Run Code Online (Sandbox Code Playgroud)
我可以看到它有效,但我不明白Applicative(或Functor)的实例来自哪里.
这种努力是否通常能使功能无点?
C. *_*ann 18
这是来自普通类型的函数的Applicative实例((->) r).它通过复制一个用于所有这些参数的参数,将具有相同第一个参数类型的函数组合到一个函数中.(<$>)是功能组合,纯粹是const,这里的内容(<*>)转换为:
s :: (r -> a -> b) -> (r -> a) -> r -> b
s f g x = f x (g x)
Run Code Online (Sandbox Code Playgroud)
这个函数可能更好地称为S组合子.
该((->) r)函子也是Reader单子,其中共享参数是"环境"的值,例如:
newtype Reader r a = Reader (r -> a)
Run Code Online (Sandbox Code Playgroud)
我不会说这是常见的用于制造功能点自由的缘故做到这一点,但在某些情况下,它实际上可以提高清晰度,一旦你习惯的成语.例如,您给出的示例我可以非常轻松地阅读"含义字母或数字".
您可以从Control.Applicative包中免费获得所谓静态箭头的实例(请参阅Conor McBride等人的"使用效果进行应用编程").因此,在您的情况下Char,任何源类型都会产生一个Applicative实例,其中任何其他类型a都映射到该类型Char -> a.
当你将这些中的任何一个组合起来时,比如将一个函数f :: Char -> a -> b应用于一个值x :: Char -> a,语义就是你创建一个新的函数Char -> b,它将它的参数输入到两者中f,x就像这样,
f <*> x = \c -> (f c) (x c)
Run Code Online (Sandbox Code Playgroud)
因此,正如您所指出的,这使您的示例等效于
isAlphaNum c = (isAlpha c) || (isNum c)
Run Code Online (Sandbox Code Playgroud)
在我看来,这样的努力并不总是必要的,如果Haskell对应用程序有更好的语法支持(可能类似于2级语言),它看起来会更好.