Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
509 views
in Technique[技术] by (71.8m points)

f# - Keeping partially applied function generic

Is it possible to partially apply a function such as bprintf and prevent it from being restricted based on its initial use?

I'd like to do the following:

let builder = new System.Text.StringBuilder()
let append = Printf.bprintf builder
append "%i" 10
append "%s" string_value
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The aspect of F# that's causing this is called value restriction. You can see that if you enter just the two let declarations to F# Interactive (so that the compiler doesn't infer the type from the first use):

> let builder = new System.Text.StringBuilder() 
  let append = Printf.bprintf builder ;;

error FS0030: Value restriction. The value 'append' has been inferred to have generic type val append : ('_a -> '_b) when '_a :> Printf.BuilderFormat<'_b> Either make the arguments to 'append' explicit or, if you do not intend for it to be generic, add a type annotation.

There is an excellent article by Dmitry Lomov from the F# team which explains it in detail. As the article suggests, one solution is to add explicit type parameter declaration:

let builder = new System.Text.StringBuilder() 
let append<'T> : Printf.BuilderFormat<'T> -> 'T = Printf.bprintf builder 
append "%i" 10 
append "%s" "Hello"

This will work just fine.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...