PureScript中函数组合与柯里化的交互及编译报错解析
1. isSomething的通用名称
你实现的isSomething函数在PureScript标准库Data.Maybe模块里有现成实现,叫做isJust,类型和功能完全一致:forall a. Maybe a -> Boolean,专门用来判断Maybe值是否为Just构造器(即不为Nothing)。
2. 函数组合写法的编译错误原因
先明确各函数的类型
findEntryByName的类型是String -> String -> AddressBook -> Maybe Entry,PureScript函数默认柯里化,等价于String -> (String -> (AddressBook -> Maybe Entry))——每传入一个参数,就返回接收剩余参数的新函数。isSomething(即isJust)的类型是forall a. Maybe a -> Boolean,接收Maybe类型值,返回布尔值。- 函数组合运算符
<<<的类型是forall b c a. (b -> c) -> (a -> b) -> (a -> c),要求右侧函数的输出类型必须等于左侧函数的输入类型,才能完成组合。
错误写法的问题
isInBook = isSomething <<< findEntryByName中,findEntryByName未传入任何参数,返回值类型是String -> AddressBook -> Maybe Entry(一个等待接收剩余两个参数的函数),而isSomething需要的输入是Maybe a类型。两者类型完全不匹配,因此编译器报错“无法匹配Function String与Maybe类型”——本质是函数组合的两端类型不兼容。
正确写法的逻辑
isInBook first last = isSomething <<< findEntryByName first last中,findEntryByName first last已传入first和last两个参数,此时返回值类型是AddressBook -> Maybe Entry。这个函数的输出是Maybe Entry,正好匹配isSomething的输入类型Maybe a,通过<<<组合后得到AddressBook -> Boolean类型的函数。再加上外层的first和last参数,整个isInBook的类型就正好是题目要求的String -> String -> AddressBook -> Boolean,符合类型系统要求,因此可以正常编译。
内容的提问来源于stack exchange,提问作者Chris Wesseling

