首页 文章

将函数应用于列表中的每个元组

提问于
浏览
5

对不起,如果这是非常基础的,我是函数式编程和F#的新手 .

我必须创建一个函数,它接受一个元组列表(string * int)并返回一个元组列表(string * int)

所以基本上我想将一些函数应用于pairList中的每个元组并返回一个元组列表 .

我猜我可以通过递归函数来做到这一点 .

到目前为止,我有以下代码:

let rec aFunction (pairList:List<string*int>): List<string*int> =
  match pairList with
  | [] -> []
  | head :: tail ->  [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))]

这基本上只是将各种函数应用于列表的头部并返回一个元组列表 .

为了使它适用于整个列表,我尝试了以下方法:

| head :: tail ->  [fst head,snd (someFunc1 (someFunc2 (fst head,snd head)));aFunction tail]

但是我收到以下错误:

该表达式应该具有类型字符串* int,但这里的类型为List <string * int>

3 回答

  • 5

    事实上这个功能确实存在 - 它被称为 List.map .

    要分析您的错误,当您执行 [a;b] ab 时需要具有相同的类型 .

    你想要的是像这样使用连接运算符 ::

    | head :: tail ->  (fst head,snd (someFunc1 (someFunc2 (fst head,snd head)))) :: (aFunction tail)
    

    但你可以通过模式匹配以更好的方式使这个整洁

    | (a,b) :: tail ->  (a,snd (someFunc1 (someFunc2 (a,b)))) :: (aFunction tail)
    
  • 5

    约翰·帕尔默斯的回答非常好,但为了清晰和可读性,我可能会一路走下去做以下事情:

    let someFunc1 = id //just to make it compile
    let someFunc2 = id //just to make it compile
    
    let someFunc3 = someFunc2 >> someFunc1 >> snd
    let someFunc4 head = fst head, someFunc3 head 
    
    let rec aFunction (pairList:List<string*int>): List<string*int> =
      match pairList with
      | [] -> []
      | head :: tail -> someFunc4 head :: (aFunction tail)
    
  • 4

    这是John提到的 List.map 选项:

    // make a helper function that converts a single tuple
    let convertTuple (s, i) =
      let i1 = (s, i) |> someFunc2 |> someFunc1 |> snd // pipeline operator helps remove parens
      s, i1
    
    // now you can simply
    let aFunction pairList = List.map convertTuple pairList
    
    // or even more simply using pointfree syntax:
    let aFunction = List.map convertTuple
    

    注意上面的 aFunction 是如此简单,你甚至可能不需要它的特殊功能:它可能更直观,只需在你需要的任何地方输出 List.map convertTuple myList .

    这是F#的总体思路;从一些助手开始,这些助手是您想要制作的最小变换,然后使用组合器将它们构建成更大的东西 .

相关问题