如何让一个函数[a] - > [a]在[(a,Int)]上运行? [英] How to let a function [a] -> [a] operate on [(a,Int)]?

查看:162
本文介绍了如何让一个函数[a] - > [a]在[(a,Int)]上运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  foo xs = map snd $ filter((< 10) .fst)$ zip xs [0 ..] 

bar ys = map snd $ sortBy(compare`on`fst)$ zip ys [0 ..]


  foo = indexesOf(filter(< 10))

bar = indexesOf sort

indexesOf ::([a] - > [a]) - > [a] - > [Int]
indexesOf f xs = map snd $ magick $ zip xs [0 ..]其中
magick = undefined

如何执行 magick

解决方案

您的类型签名不起作用。你需要能够给传递的函数一个元组列表,这意味着你必须使用更高级别的类型来强制它是多态的,或者在你的类型签名中明确提及元组。



如果没有这个,你不能查看函数来查看它是如何重新排列列表中的元素的。实际上,给定你的类型签名,传递的函数可以对列表做任何事情,包括插入甚至不在其中的元素!



以下是我使用高级别类型的工作:

  { - #LANGUAGE RankNTypes# - } 

import Data.List(sortBy)
import Data.Ord(比较)

indexesOf ::(forall b。 (b→a)→b→→b→)→> [a] - > [Int]
indexesOf f xs = map snd $ f fst $ zip xs [0 ..]

foo ::(Ord a,Num a)=> [a] - > [Int]
foo = indexesOf(filter。((<10)。))

bar :: Ord a => [a] - > [Int]
bar = indexesOf(sortBy。comparison)

请注意,我也必须为传递的函数添加一个额外的参数,告诉它如何从它正在处理的列表的元素中提取它关心的部分。如果没有这个,你只能使用不检查列表元素的函数,比如 reverse ,这不会很有用。



GHCi中的示例运行:

 > ;令xs = [42,0,7,3,12,17,99,36,8] 
> foo xs
[1,2,3,8]
>栏xs
[1,3,2,8,4,5,7,0,6]
> indexesOf(const reverse)xs
[8,7,6,5,4,3,2,1,0]


I find myself often writing code following the pattern:

foo xs = map snd $ filter ((< 10).fst) $ zip xs [0..]

bar ys = map snd $ sortBy (compare `on` fst) $ zip ys [0..]

Now I want to abstract this away

foo = indexesOf (filter (<10))

bar = indexesOf sort

indexesOf :: ([a] -> [a]) -> [a] -> [Int] 
indexesOf f xs = map snd $ magick $ zip xs [0..] where
    magick = undefined

How to perform the magick?

解决方案

Your type signature won't work. You need to be able to give the passed function a list of tuples, which means that you either have to use higher-rank types to force it to be polymorphic, or explicitly mention tuples in your type signature.

Without this, you can't "look inside" the function to see how it rearranges the elements of the list. In fact, given your type signature the passed function could do anything it wanted to the list, including inserting elements that weren't even in there to begin with!

Here's what I got to work using higher-rank types:

{-# LANGUAGE RankNTypes #-}

import Data.List (sortBy)
import Data.Ord (comparing)

indexesOf :: (forall b. (b -> a) -> [b] -> [b]) -> [a] -> [Int]
indexesOf f xs = map snd $ f fst $ zip xs [0..]

foo :: (Ord a, Num a) => [a] -> [Int]
foo = indexesOf (filter . ((< 10) .))

bar :: Ord a => [a] -> [Int]
bar = indexesOf (sortBy . comparing)

Note that I also had to add an extra argument to the passed function to tell it how to extract the part it cares about from the elements of the list it's working on. Without this, you would only be able to use functions that don't inspect the elements of the list, such as reverse, and that wouldn't be very useful.

Example run in GHCi:

> let xs = [42, 0, 7, 3, 12, 17, 99, 36, 8]
> foo xs
[1,2,3,8]
> bar xs
[1,3,2,8,4,5,7,0,6]
> indexesOf (const reverse) xs
[8,7,6,5,4,3,2,1,0]

这篇关于如何让一个函数[a] - &gt; [a]在[(a,Int)]上运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆