fsharp
fsharp copied to clipboard
One of our negative test cases had an error that changed from attractive to spaghetti
The error produced by:
module Applicatives =
open System
type Ap = Ap with
static member inline Invoke (x:'T) : '``Applicative<'T>`` =
let inline call (mthd : ^M, output : ^R) = ((^M or ^R) : (static member Return: _*_ -> _) output, mthd)
call (Ap, Unchecked.defaultof<'``Applicative<'T>``>) x
static member inline InvokeOnInstance (x:'T) = (^``Applicative<'T>`` : (static member Return: ^T -> ^``Applicative<'T>``) x)
static member inline Return (r:'R , _:obj) = Ap.InvokeOnInstance :_ -> 'R
static member Return (_:seq<'a> , Ap ) = fun x -> Seq.singleton x : seq<'a>
static member Return (_:Tuple<'a>, Ap ) = fun x -> Tuple x : Tuple<'a>
static member Return (_:'r -> 'a , Ap ) = fun k _ -> k : 'a -> 'r -> _
let inline result (x:'T) = Ap.Invoke x
let inline (<*>) (f:'``Applicative<'T->'U>``) (x:'``Applicative<'T>``) : '``Applicative<'U>`` =
(( ^``Applicative<'T->'U>`` or ^``Applicative<'T>`` or ^``Applicative<'U>``) : (static member (<*>): _*_ -> _) f, x)
let inline (+) (a:'Num) (b:'Num) :'Num = a + b
type ZipList<'s> = ZipList of 's seq with
static member Return (x:'a) = ZipList (Seq.initInfinite (fun _ -> x))
static member (<*>) (ZipList (f:seq<'a->'b>), ZipList x) = ZipList (Seq.zip f x |> Seq.map (fun (f, x) -> f x)) :ZipList<'b>
type Ii = Ii
type Idiomatic = Idiomatic with
static member inline ($) (Idiomatic, si) = fun sfi x -> (Idiomatic $ x) (sfi <*> si)
static member ($) (Idiomatic, Ii) = id
let inline idiomatic a b = (Idiomatic $ b) a
let inline iI x = (idiomatic << result) x
let res1n2n3 = iI (+) (result 0M ) (ZipList [1M;2M;3M]) Ii
let res2n3n4 = iI (+) (result LanguagePrimitives.GenericOne) (ZipList [1 ;2 ;3 ]) Ii
repro:
c:\kevinransom\fsharp>fsc C:\kevinransom\fsharp\tests\fsharp\typecheck\sigs\neg119a.fs --langversion:6.0
Microsoft (R) F# Compiler version 12.0.6.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
C:\kevinransom\fsharp\tests\fsharp\typecheck\sigs\neg119.fs(40,20): error FS0071: Type constraint mismatch when applying the default type 'obj' for a type inference variable. No overloads match for method 'Return'.
Known return type: ((int -> int -> int) -> obj)
Known type parameters: < obj , Applicatives.Ap >
Available overloads:
- static member Applicatives.Ap.Return: ('r -> 'a) * Ap: Applicatives.Ap -> (('a -> 'r -> 'a2) -> 'a3 -> 'a -> 'r -> 'a2) // Argument at index 1 doesn't match
- static member Applicatives.Ap.Return: System.Tuple<'a> * Ap: Applicatives.Ap -> ('a -> System.Tuple<'a>) // Argument at index 1 doesn't match
- static member Applicatives.Ap.Return: r: ^R * obj -> ('a1 -> ^R) when ^R: (static member Return: 'a1 -> ^R) // Argument 'r' doesn't match
- static member Applicatives.Ap.Return: seq<'a> * Ap: Applicatives.Ap -> ('a -> seq<'a>) // Argument at index 1 doesn't match Consider adding further type constraints
c:\kevinransom\fsharp>fsc C:\kevinransom\fsharp\tests\fsharp\typecheck\sigs\neg119.fs --langversion:preview
Microsoft (R) F# Compiler version 12.0.6.0 for F# 6.0
Copyright (c) Microsoft Corporation. All Rights Reserved.
C:\kevinransom\fsharp\tests\fsharp\typecheck\sigs\neg119.fs(40,9): error FS0030: Value restriction. The value 'res2n3n4' has been inferred to have generic type
val res2n3n4: ^_a when (^_b or Applicatives.ZipList<int> or ^_a) : (static member (<*>) : ^_b * Applicatives.ZipList<int> -> ^_a) and (^_c or obj or ^_b) : (static member (<*>) : ^_c * obj -> ^_b) and (Applicatives.Ap or ^_c) : (static member Return: ^_c * Applicatives.Ap -> ((int -> int -> int) -> ^_c))
Either define 'res2n3n4' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
Do you see what I mean? The error may be more accurate, but probably needs formatting to make it readable by a tiny brain like myself.
neg119.fs is being renamed to neg119a.fs in a forthcoming pr, so, try that if you get file not found.
How do you like this formatting?
Value restriction. The value 'res2n3n4' has been inferred to have generic type
val res2n3n4: ^_a when (^_b or Applicatives.ZipList<int> or ^_a) : (static member (<*>) : ^_b * Applicatives.ZipList<int> -> ^_a)
and (^_c or obj or ^_b) : (static member (<*>) : ^_c * obj -> ^_b)
and (Applicatives.Ap or ^_c) : (static member Return: ^_c * Applicatives.Ap -> ((int -> int -> int) -> ^_c))
Either define 'res2n3n4' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
https://github.com/dotnet/fsharp/pull/13727