我目前正在学习Clojure并且它非常具有智力刺激性,但我遇到了很多可以编程解决问题的情况(例如4Clojure),但是找到了其他解决方案使用我完全没有意识到的大量其他功能。
除了阅读所有文档或至少所有名称空间之外,还有解决方案来解决函数式编程中的可发现问题吗?这个问题的必然结果是,如果有一个解决方案,不能在软件工程团队中重复人员之间的努力。如果我需要一个新功能,或者我的队友已经实现了它,有没有办法可以发现?有没有办法让她发现我的功能?也就是说,如果没有我们正在构建的整个系统的某种总体功能分解。
是否存在可以帮助我发现基于使用的新功能的本体或函数映射。例如,一种对foldl和foldr进行分类的方法,以便我可以轻松地发现foldl'存在(或可能存在)和折叠'不需要存在吗?我可以通过某种方式看到一个暗区"地图,并知道那里可能有一个功能,它会做什么。
是否存在某个问题或数据类型和功能的数据库?
答案 0 :(得分:6)
根据许多人的良好开端是能够谈论类型。在Haskell世界中,他们甚至拥有基于类型的搜索引擎!例如,假设您具有类型Maybe Int
的值,并且如果存在值则要将其转换为字符串,否则提供空字符串。在类型方面,这是一个函数
f' :: Maybe Integer -> (Integer -> String) -> String -> String
它需要三个参数 - Maybe
值,转换函数,默认值,它将返回一个字符串。如果我们使这更加通用,我们可能会得到像
f :: Maybe a -> (a -> b) -> b -> b
通过using this as a query for the type-based search engine,我们会发现确实有一个函数
maybe :: b -> (a -> b) -> Maybe a -> b
在Data.Maybe
库中执行我们想要的操作。
当然,这并不完美。一个问题是您可以在不同的抽象级别表达相同的操作。例如,想象一下,我们有一个整数列表,我们要将其转换为Text
值,然后连接。对类型签名的第一次尝试会产生类似
g' :: [Int] -> (Int -> Text) -> Text
如果我们搜索这个,我们找不到明确的结果。可能不会立即明确如何使这更抽象。也许它应该是这样的?
g :: [a] -> (a -> b) -> ([b] -> b) -> b
(换句话说,给定一个a
列表,一个转换函数,以及一个告诉你如何连接b
的函数,返回一个b
。)搜索这会产生各种结果,所有结果都与我们的应用完全无关。
这里的关键见解,不是推理,而是经验和知识,是我们真正想要的东西已经知道如何连接自己。我们想要一个Monoid
操作函数。基于这些知识,我们更有可能找到
foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m
- 正是我们所寻找的。 p>
所以类型不是一个完美的系统,但它们确实有帮助。他们工作的原因是因为他们试图编码程序员的意图。你真正要求的是一种意图数据库,而不是实现(源代码是。)
更好的类型系统只允许程序员更好地编码他们的意图,从而使这个过程更加顺畅。但是他们总是需要纪律,例如使用最常用的类型。
更一般类型的情况是,更一般的类型限制属于同一类型的意图的数量。在没有上下文的情况下,类型为a -> b -> a
的函数只能执行一项操作 - 忽略其第二个参数并返回第一个参数。另一方面,类型String -> b -> String
的函数可以做任何想做的事情,因为它知道如何构造自己的返回类型的值。如果函数不知道它的返回类型,它只能通过使用它得到的参数来构造它。
答案 1 :(得分:0)
Haskell有hoogle,您可以根据类型签名(和名称)进行搜索。我在学习时发现这非常有用。只要你知道自己想要实现的目标,你就可能找到与你所追求的相近的东西。
例如,您可以搜索(b-> c) - > (a-> b) - > a - > c,搜索带来了(。),用于编写函数。