2017-10-24 12 views
1

私のaddLink関数が呼び出されない理由はまだわかりません。Seq.mapの関数が実行されないのはなぜですか?

私は次のコードを持っている:まず

let links = source |> getLinks 
let linkIds = links |> Seq.map addLink // addLink never gets executed 

を、私はリンク値が空だと思いました。

ただし、そうではありません。

let count = Seq.length links // Returns over 100 items 

注:

私は関数を実行することができた唯一の方法は、最初で実行されている:

let count = linkIds |> Seq.length // Call this after performing map 

なぜ私はそれは次のように呼び出すことによって移入されたことを確認し私の機能を呼び出すためだけにそれをする必要がありますか?

付録:

let addLink (info:Link) = 
    let commandFunc (command: SqlCommand) = 
     command |> addWithValue "@ProfileId"  info.ProfileId 
       |> addWithValue "@Title"   info.Title 
       |> addWithValue "@Description" info.Description 
       |> addWithValue "@Url"   info.Url 
       |> addWithValue "@ContentTypeId" (info.ContentType |> contentTypeToId) 
       |> addWithValue "@IsFeatured" info.IsFeatured 
       |> addWithValue "@Created"  DateTime.Now 

    commandFunc |> execute connectionString addLinkSql 


[<CLIMutable>] 
type Link = { 
    Id:   int 
    ProfileId:  string 
    Title:   String 
    Description: String 
    Url:   string 
    Topics:  Topic list 
    ContentType: string 
    IsFeatured: bool 
} 

ここsource codeです。

+0

あなたは今まで 'linkIds'の値を使っていますか? – sepp2k

+0

SeqはC#のIEnumerableと同じですが、実際に結果を使用するまで実行されません。 Seq.lengthを呼び出すことによって、シーケンスを評価する必要があります。直ちにそれをただちに除去したいのであれば、例えばSeq.iter ignoreにパイプすることができます。 – hlo

+1

遅延評価 –

答えて

7

Seq<'a>は、怠け者であるIEnumerable<'a>と同じです。つまり、シーケンス内の各要素は必要に応じて評価されるだけです。副作用が確実に呼び出されるようにするには、Seq.toListを追加してリストのような具象データ構造に変換することができます。

ただし、副作用を実行するコードを値を返すコードに別々に記述する方がよいでしょう。ある関数でlinkIdsを計算し、Seq.iterを使用して別の関数で副作用を実行すると、シーケンスを完全に評価することができます。

関連する問題