Keeping partially applied function generic

梦想与她 提交于 2019-11-29 10:21:27

you can add explicit format argument

let builder = new System.Text.StringBuilder()
let append format = Printf.bprintf builder format
append "%i" 10
append "%s" "1"

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.

Tim Robinson

You're encountering the F# value restriction.

Here's a good explanation of some workarounds: Understanding F# Value Restriction Errors

Here's a fairly in-depth article explaining the reasons behind it: http://blogs.msdn.com/b/mulambda/archive/2010/05/01/value-restriction-in-f.aspx

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!