首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >按fst筛选元组列表

按fst筛选元组列表
EN

Stack Overflow用户
提问于 2016-03-16 14:56:01
回答 2查看 872关注 0票数 1

我想要做的不是真正解决问题,而是学习如何编写Haskell代码,编写/利用基本函数来完成。

我有一个函数,它接受元组( String,Int)和字符串的列表,并返回一个tuple,其fst与给定的字符串匹配。这对于过滤器和lambda来说相当容易,但是我现在要做的是删除最正确的论点,即。我希望重构这个函数,使之成为部分应用的函数的组合,这些函数将执行相同的功能。

原来的代码是:

代码语言:javascript
复制
getstat :: Player -> String -> Stat
getstat p n = head $ filter (\(n', v) -> n' == n) $ stats p

新代码是:

代码语言:javascript
复制
getstat :: Player -> String -> Stat
getstat p = head . (flip filter $ stats p) . cmpfst
    where cmpfst = (==) . fst . (flip (,)) 0  -- Wrong :-\

其思想是翻转过滤器和部分应用在元组列表(stats )中,然后组成cmpfst。cmpfst应该是String -> ( String,Int) -> Bool,这样当String参数被应用时,它就变成了一个-> Bool,这有利于过滤器传递元组,但是正如您所看到的--我有问题组成(==),因此只比较给定元组的fst。

我知道第一段代码可能更简洁;这个任务的目的不是编写干净的代码,而是学习如何通过组合解决问题。

编辑:

我很清楚,在一个可能是空的列表上要求一个标题是一个糟糕的程序,会导致崩溃。就像前面提到的一张海报一样,它非常简单而优雅地解决了也许是单一的问题--这是我以前做过的,也是我所熟悉的。

我想要关注的是,如何使cmpfst主要由基本功能组成。到目前为止,我得到的是:

代码语言:javascript
复制
getstat :: Player -> String -> Stat
getstat p = head . (flip filter $ stats p) . (\n' -> (==(fst n')) . fst) . (flip (,)) 0

我无法通过编写和部分应用-> (==)来摆脱(一个==)λ。对我来说,这意味着我要么不明白自己在做什么,要么就不可能以我想象的方式使用(==)操作符。

此外,除非没有确切的解决方案,否则我将接受签名更改方案作为正确的解决方案。我不想更改函数的签名,仅仅因为它对我来说是一种心理练习,而不是一种生产代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-16 17:05:51

在一条评论中,你联系了

代码语言:javascript
复制
getstat p = head . (flip filter $ stats p) . (\n (n', v) -> n' == n)

我想知道是否有一种更好的成分可以消除anon f。

好吧,在这里

代码语言:javascript
复制
\n (n', v) -> n' == n
-- for convenience, we flip the ==
\n (n', v) -> n == n'
-- prefix notation
\n (n', v) -> (==) n n'
-- let's remove pattern matching over (n', v)
\n (n', v) -> (==) n $ fst (n', v)
\n x -> (==) n $ fst x
-- composition, eta
\n -> (==) n . fst
-- prefix
\n -> (.) ((==) n) fst
-- composition
\n -> ((.) . (==) $ n) fst
-- let's force the application to be of the form (f n (g n))
\n -> ((.) . (==) $ n) (const fst $ n)
-- exploit f <*> g = \n -> f n (g n)   -- AKA the S combinator
((.) . (==)) <*> (const fst)
-- remove unneeded parentheses
(.) . (==) <*> const fst

删除p是作为练习留下的。

票数 1
EN

Stack Overflow用户

发布于 2016-03-16 15:22:53

如果我要编写这个函数,我可能会给它这种类型的签名:

代码语言:javascript
复制
getstat :: String -> Player -> Stat

这使得eta很容易将定义简化为

代码语言:javascript
复制
getstat n = head . filter ((== n) . fst) . stats
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36039245

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档