Заполнить словарь рекурсивно? - PullRequest
1 голос
/ 02 апреля 2011

Я тестирую следующий код для рекурсивного заполнения словаря.Однако вывод типа не распознает тип словаря.Я попытался использовать аннотацию типа, но это, похоже, не помогло.

Существуют ли ограничения на использование словарей в рекурсивной процедуре.Нужно ли сделать словарь изменчивым, поскольку я ожидаю изменить его во время итераций.

open System
open System.Collections.Generic

////dictionary recursion test

let pop_dict tlist = 
   // let rec inner tlist acc ddict:Dictionary<string,int> =
    let rec inner tlist acc ddict =
       match tlist with 
            | [] ->  ddict.Add ("dummykey", acc)                             
            | x::xs  -> inner xs  (x::acc) ddict
    let  ddict = Dictionary<string,int>()
    inner tlist [] ddict 


// Main Entry Point
let main() =

    let tlist = [1;2;3;4]
    let d = pop_dict tlist

main()

Ответы [ 2 ]

4 голосов
/ 02 апреля 2011

Прежде всего, ваши типы не совпадают.

Вы пытаетесь добавить int list (что такое acc) в словарь, который должен содержать int s.

Однако, кроме того, причина, по которой компилятор не может определить тип ddict, заключается в. Помните, что когда средство проверки типов определяет типы для функции, она не смотрит на то, с чем она вызывается позже. Имеется только следующая информация:

let rec inner tlist acc ddict =
   match tlist with 
        | [] -> ddict.Add ("dummykey", acc)                             
        | x::xs  -> inner xs  (x::acc) ddict

Это означает, что единственная информация, которую он знает о ddict при компиляции функции, это то, что у него есть метод с именем Add, который string * 'a list -> ?.

Чтобы исправить это, измените

let rec inner tlist acc ddict =

до

let rec inner tlist acc (ddict:Dictionary<string,int>) =

Однако у вас все еще есть проблема с несовпадающими типами в словаре, поэтому вы, вероятно, захотите, чтобы оно было Dictionary<string, int list>, если вы планируете хранить в нем int list s.

1 голос
/ 02 апреля 2011

это то, что вы хотели?

let pop_dict tlist = 
    let rec inner tlist acc (ddict:Dictionary<string,int list>) =
       match tlist with 
            | [] ->  ddict.Add ("dummykey", acc)                             
            | x::xs  -> inner xs  (x::acc) ddict
    let  ddict = Dictionary<string,int list>()
    inner tlist [] ddict 


// Main Entry Point
let main() =

    let tlist = [1;2;3;4]
    let d = pop_dict tlist
    ()
...