2011-06-26 23 views
1

で書かれたサンプルを修正するスペルエラーを修正しようとする試みについて、ここではクールなブログ記事がありますが、古いバージョンのF#で書かれています。
http://blog.lab49.com/archives/2841 私は物事が間違っていると思うすべての帽子にコメントを書いた最後を除いて、ほとんどを修正しました。基本的にはいくつかの場所でSetが期待され、Map <>が与えられ、その逆もあります。私はこのコードを何時間も見つめていて、どこがミスマッチになっているのか分からないようです。古いバージョンのF#

open System 
open System.Linq 


///'k represents the base key type, and 'a represents the element type. 
type trie<'k,'a when 'k : comparison> = TNode of ('a option * Map<'k,trie<'k,'a>>) 

///'ks represents a type that stores a sequence of the key elements, and 'k represents the type of the key elements. 
type iter_module<'ks,'k> = 
    { 
     eos : ('ks -> bool) //whether or not a key-sequence is at its end. 
     head : ('ks -> 'k) //gets the current key-value in a key sequence 
     tail : ('ks -> 'ks) // increments the key-sequence iterator. 
    } 

let siterm : iter_module<string * int, char> = 
    { 
     eos = fun (s,i) -> i >= String.length s 
     head = fun (s,i) -> s.[i] 
     tail = fun (s,i) -> (s, i+1) 
    } 

///Extracts the option value associated with a node. 
let node_value = function 
| TNode (ov,_) -> ov 

///Extracts the map representing connections from the current trie node to sub-trees. 
let node_map = function 
| TNode (_, m) -> m 

///Determines whether a trie is empty 
let is_empty tn = Map.isEmpty (node_map tn) 

///Empty trie. 
let empty_trie = TNode (None, Map.empty) 

/// <summary> 
/// Find a sub-trie. 
/// </summary> 
/// <param name="tn">The current trie node.</param> 
/// <param name="k">The key.</param> 
let find_subtrie tn k = 
    try 
     Map.find k (node_map tn) 
    with 
     not_found -> empty_trie 

/// <summary> 
/// Update the trie. 
/// </summary> 
/// <param name="m">The iteration module.</param> 
/// <param name="tn">The trie node.</param> 
/// <param name="ks">a sequence of the key elements</param> 
/// <param name="v">Option containing the element</param> 
let add m tn ks v = 
    let rec upd tn' ks' = 
     if(m.eos ks') then 
      TNode(Some v, (node_map tn')) 
     else 
      let k = (m.head ks') in 
      let ov = node_value tn' in 
      let tn'' = upd(find_subtrie tn' k)(m.tail ks') in 
       TNode(ov, Map.add k tn'' (node_map tn')) 
    in 
     upd tn ks 

/// <summary> 
/// Lookup the option value associated with a string 
/// </summary> 
/// <param name="m">The iteration module.</param> 
/// <param name="tn">The trie node.</param> 
/// <param name="ks">a sequence of the key elements</param> 
let lookup m tn ks = 
    let rec lv tn' ks' = 
     if(m.eos ks') then 
      node_value tn' 
     else 
      let k = (m.head ks') in 
       lv(find_subtrie tn' k)(m.tail ks') 

    in 
     lv tn ks 

/// <summary> 
/// Determine whether or not a specific work is valid in the trie by a simple use of the lookup function. 
/// </summary> 
/// <param name="m">The iteration module.</param> 
/// <param name="tn">The trie node.</param> 
/// <param name="ks">a sequence of the key elements</param> 
let mem m tn ks = 
    match(lookup m tn ks) with 
    | Some _ -> true 
    | None -> false 

/// <summary> 
/// Determines the suffix of a string 
/// </summary> 
/// <param name="s">The string to find the suffix of.</param> 
/// <param name="i">The starting point of the suffix.</param> 
let suffix(s:String,i) = s.Substring(i,(String.length s - i)) 

/// <summary> 
/// Computes the set of words defined by a trie node if we follow any valid character from that node, and then try to follow a specific char sequences. 
/// </summary> 
/// <param name="pfx">The prefix.</param> 
/// <param name="trie">The trie node.</param> 
/// <param name="wi">Word index.</param> 
/// <param name="words">The words.</param> 
let strings_with_suffix pfx trie wi words = 
let accumulate_paths c trie' ws = 
    if (mem siterm trie' wi) then 
    Set.add (pfx + (string c) + (suffix wi)) ws 
    else 
    ws 
in 
//THIS IS WHERE THINGS APPEAR TO BE GOING WRONG 
Map.fold accumulate_paths (node_map trie) words 

/// <summary> 
/// Spelling correction suggestions. 
/// </summary> 
/// <param name="trie">The trie.</param> 
/// <param name="word">The mispelled word.</param> 
let suggestions trie word = 
    let rec paths_around_char pfx trie wi words = 
    if (siterm.eos wi) then 
    strings_with_suffix pfx trie ("", 0) words 
    else if (is_empty trie) then 
    words 
    else 
    let c  = siterm.head wi in 
    let wi' = siterm.tail wi in 
    let trie' = find_subtrie trie c in 
    let ins_ws = strings_with_suffix pfx trie wi words in 
    let rep_ws = strings_with_suffix pfx trie wi' ins_ws in 
    let del_ws = if (mem siterm trie wi') then 
        Set.add (pfx + (suffix wi')) rep_ws 
       else 
        rep_ws 
    in 
    paths_around_char (pfx + (string c)) trie' wi' del_ws 
    in 
    paths_around_char "" trie (word, 0) Set.empty 

事前のおかげで、

ボブ

答えて

2

は(F#標準ライブラリの古いバージョンが異なるパラメータの順序を持​​っている)という問題がMap.foldの異なる署名にあるようですin strings_with_suffix

sign倍のature:( '国家 - >' キー - > '値 - >' 州) - > '国家 - >地図<' キー '値> - >' 国家

現在の呼び出し場所:

let strings_with_suffix pfx trie wi words = 
    let accumulate_paths c trie' ws (* 2 *)= 
     if (mem siterm trie' wi) then 
      Set.add (pfx + (string c) + (suffix wi)) ws 
     else 
      ws 
in 
//THIS IS WHERE THINGS APPEAR TO BE GOING WRONG 
Map.fold accumulate_paths (node_map trie) (* 1 *) words 

  1. 呼び出し側は、最後の引数として国家ではなく、最初の

正しいバージョンは次のようになります「受け入れない最初の

  • accumulate_paths、最後のパラメータとして国家」をを渡します
    let strings_with_suffix pfx trie wi words = 
        let accumulate_paths ws c trie' = 
         if (mem siterm trie' wi) then 
          Set.add (pfx + (string c) + (suffix wi)) ws 
         else 
          ws 
        in 
        Map.fold accumulate_paths words (node_map trie) 
    
  • +0

    うん、それは大丈夫だった。ありがとう、デコ! – Beaker

    関連する問題