【问题标题】:( F#) Indexing a String without type annotating the string( F#) 对字符串进行索引而不对字符串进行类型注释
【发布时间】:2016-04-14 05:44:01
【问题描述】:

嘿,我的任务要求之一是我不使用类型注释。

目前我的代码是这样的

let (currentSeq: string) = 
            specie 
            |> Map.tryFind geneId 
            |> Option.get
let seq1 = currentSeq.[0..pos - 1]
let seq2 = currentSeq.[pos..String.length currentSeq - 1]`

我已经绞尽脑汁一段时间了,但我不知道如何在没有类型注释的情况下索引字符串 currentSeq 的“块”。

【问题讨论】:

  • 有些时候你会被类型注释困住——这可能就是其中之一
  • 这可能被认为是作弊,但您可以在技术上告诉编译器您有一个字符串,而无需使用类型注释,方法是将值传递给任何需要字符串的函数,然后再在代码中使用该值,甚至如果你扔掉结果。例如,String.length specie |> ignore 将为编译器确定 specie 必须是一个字符串,并且在那之后您将被允许以这种方式对待它。

标签: indexing f#


【解决方案1】:

IIUYC,你需要将一个字符串分成两个而不使用类型注释。这里有一个方法:

let splitAt s pos = 
  let length = s |> String.length
  [ s.[0..pos - 1]; s.[pos..length - 1] ]

【讨论】:

  • 这似乎不是最好的方法,但它确实有效 :) 我喜欢它!
  • 我认为这可能是最好和最干净的解决方案。通常,如果您想避免类型注释,请记住编译器按其显示的顺序处理表达式。首先放置一些表达式,编译器可以从中立即推断出类型 - 这是 @yuyoyupe 在代码中对 String.length 的调用。从那一刻起,一切都很好。
  • 我意识到我可以简单地将String.length currentSeq 移动到我尝试索引字符串的行上方,它不再需要类型推断。 IE。结果:let strLength = String.length currentSeq let newSeq = currentSeq.[0..pos - 1] + inSeq + currentSeq.[pos..strLength - 1] 我不完全理解编译器,但我认为这是因为它现在有一个引用点,currentSeq 被视为字符串。
  • @OliverGiess 是的,完全正确。不要忘记接受答案,这样它就不会混乱了
【解决方案2】:

您无需键入注释:

let currentSeq = "ojdjdsajdsa"
let seq1 = currentSeq.[0..3 - 1]

你的最后两个序列太识别了

【讨论】:

  • 整个问题是编译器不知道该对象是一个字符串,因为它是一个文字,你基本上是在作弊。此外,在问题中提议对 OP 的代码进行编辑更改,这样会更改他的代码,这种形式真的很糟糕
  • 我怀疑可能是这种情况。但是一旦我们从地图中提取geneID,编译器应该知道它是一个字符串,不是吗?例如:let rnd = System.Random()let abc = ['a'..'z']let abc' = abc |> List.map (fun x -> (x,rnd.Next(26).ToString())) |> Map.ofListlet x = abc'.TryFind 'a' |> Option.getlet z = x.[0]
  • @JohnPalmer 确实如此。可能应该先在评论中确认。
  • @s952163 那是我的错,将代码复制到堆栈中,我现在会修复它
  • 编辑了您的答案以修复代码格式 - 对于多行代码块,最好使用缩进而不是波浪号,因为使用波浪号不会给您语法高亮。编辑框中的{} 按钮正是为了这个目的:突出显示要缩进的代码并按下{} 按钮,它都会整齐地缩进四个空格,从而在您的答案中生成好看的代码。
猜你喜欢
  • 2015-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 1970-01-01
  • 2012-07-05
相关资源
最近更新 更多