@@ -907,3 +907,134 @@ end
907
907
@test isa (chopsuffix (S (" foo" ), " oo" ), SubString)
908
908
end
909
909
end
910
+
911
+ # https://github.com/JuliaLang/julia/pull/54653: add Fix
912
+ @testset " Fix" begin
913
+ function test_fix1 (Fix1= Compat. Fix1)
914
+ increment = Fix1 (+ , 1 )
915
+ @test increment (5 ) == 6
916
+ @test increment (- 1 ) == 0
917
+ @test increment (0 ) == 1
918
+ @test map (increment, [1 , 2 , 3 ]) == [2 , 3 , 4 ]
919
+
920
+ concat_with_hello = Fix1 (* , " Hello " )
921
+ @test concat_with_hello (" World!" ) == " Hello World!"
922
+ # Make sure inference is good:
923
+ @inferred concat_with_hello (" World!" )
924
+
925
+ one_divided_by = Fix1 (/ , 1 )
926
+ @test one_divided_by (10 ) == 1 / 10.0
927
+ @test one_divided_by (- 5 ) == 1 /- 5.0
928
+
929
+ return nothing
930
+ end
931
+
932
+ function test_fix2 (Fix2= Compat. Fix2)
933
+ return_second = Fix2 ((x, y) -> y, 999 )
934
+ @test return_second (10 ) == 999
935
+ @inferred return_second (10 )
936
+ @test return_second (- 5 ) == 999
937
+
938
+ divide_by_two = Fix2 (/ , 2 )
939
+ @test map (divide_by_two, (2 , 4 , 6 )) == (1.0 , 2.0 , 3.0 )
940
+ @inferred map (divide_by_two, (2 , 4 , 6 ))
941
+
942
+ concat_with_world = Fix2 (* , " World!" )
943
+ @test concat_with_world (" Hello" ) == " Hello World!"
944
+ @inferred concat_with_world (" Hello World!" )
945
+
946
+ return nothing
947
+ end
948
+
949
+ # Test with normal Base.Fix1 and Base.Fix2
950
+ test_fix1 ()
951
+ test_fix2 ()
952
+
953
+ # Now, repeat the Fix1 and Fix2 tests, but
954
+ # with a Fix lambda function used in their place
955
+ test_fix1 ((op, arg) -> Compat. Fix {1} (op, arg))
956
+ test_fix2 ((op, arg) -> Compat. Fix {2} (op, arg))
957
+
958
+ # Now, we do more complex tests of Fix:
959
+ let Fix= Compat. Fix
960
+ @testset " Argument Fixation" begin
961
+ let f = (x, y, z) -> x + y * z
962
+ fixed_f1 = Fix {1} (f, 10 )
963
+ @test fixed_f1 (2 , 3 ) == 10 + 2 * 3
964
+
965
+ fixed_f2 = Fix {2} (f, 5 )
966
+ @test fixed_f2 (1 , 4 ) == 1 + 5 * 4
967
+
968
+ fixed_f3 = Fix {3} (f, 3 )
969
+ @test fixed_f3 (1 , 2 ) == 1 + 2 * 3
970
+ end
971
+ end
972
+ @testset " Helpful errors" begin
973
+ let g = (x, y) -> x - y
974
+ # Test minimum N
975
+ fixed_g1 = Fix {1} (g, 100 )
976
+ @test fixed_g1 (40 ) == 100 - 40
977
+
978
+ # Test maximum N
979
+ fixed_g2 = Fix {2} (g, 100 )
980
+ @test fixed_g2 (150 ) == 150 - 100
981
+
982
+ # One over
983
+ fixed_g3 = Fix {3} (g, 100 )
984
+ @test_throws ArgumentError (" expected at least 2 arguments to `Fix{3}`, but got 1" ) fixed_g3 (1 )
985
+ end
986
+ end
987
+ @testset " Type Stability and Inference" begin
988
+ let h = (x, y) -> x / y
989
+ fixed_h = Fix {2} (h, 2.0 )
990
+ @test @inferred (fixed_h (4.0 )) == 2.0
991
+ end
992
+ end
993
+ @testset " Interaction with varargs" begin
994
+ vararg_f = (x, y, z... ) -> x + 10 * y + sum (z; init= zero (x))
995
+ fixed_vararg_f = Fix {2} (vararg_f, 6 )
996
+
997
+ # Can call with variable number of arguments:
998
+ @test fixed_vararg_f (1 , 2 , 3 , 4 ) == 1 + 10 * 6 + sum ((2 , 3 , 4 ))
999
+ if VERSION >= v " 1.7.0"
1000
+ @inferred fixed_vararg_f (1 , 2 , 3 , 4 )
1001
+ end
1002
+ @test fixed_vararg_f (5 ) == 5 + 10 * 6
1003
+ if VERSION >= v " 1.7.0"
1004
+ @inferred fixed_vararg_f (5 )
1005
+ end
1006
+ end
1007
+ @testset " Errors should propagate normally" begin
1008
+ error_f = (x, y) -> sin (x * y)
1009
+ fixed_error_f = Fix {2} (error_f, Inf )
1010
+ @test_throws DomainError fixed_error_f (10 )
1011
+ end
1012
+ @testset " Chaining Fix together" begin
1013
+ f1 = Fix {1} (* , " 1" )
1014
+ f2 = Fix {1} (f1, " 2" )
1015
+ f3 = Fix {1} (f2, " 3" )
1016
+ @test f3 () == " 123"
1017
+
1018
+ g1 = Fix {2} (* , " 1" )
1019
+ g2 = Fix {2} (g1, " 2" )
1020
+ g3 = Fix {2} (g2, " 3" )
1021
+ @test g3 (" " ) == " 123"
1022
+ end
1023
+ @testset " Zero arguments" begin
1024
+ f = Fix {1} (x -> x, ' a' )
1025
+ @test f () == ' a'
1026
+ end
1027
+ @testset " Dummy-proofing" begin
1028
+ @test_throws ArgumentError (" expected `N` in `Fix{N}` to be integer greater than 0, but got 0" ) Fix {0} (> , 1 )
1029
+ @test_throws ArgumentError (" expected type parameter in `Fix` to be `Int`, but got `0.5::Float64`" ) Fix {0.5} (> , 1 )
1030
+ @test_throws ArgumentError (" expected type parameter in `Fix` to be `Int`, but got `1::UInt64`" ) Fix {UInt64(1)} (> , 1 )
1031
+ end
1032
+ @testset " Specialize to structs not in `Base`" begin
1033
+ struct MyStruct
1034
+ x:: Int
1035
+ end
1036
+ f = Fix {1} (MyStruct, 1 )
1037
+ @test f isa Fix{1 ,Type{MyStruct},Int}
1038
+ end
1039
+ end
1040
+ end
0 commit comments