Skip to content

Commit cd7fdb0

Browse files
Merge pull request #648 from AayushSabharwal/as/fntype
feat: add generic to `FnType` representing type of the function
2 parents d143b79 + 1dd611e commit cd7fdb0

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

src/types.jl

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ promote_symtype(f, Ts...) = Any
912912
#### Function-like variables
913913
#---------------------------
914914

915-
struct FnType{X<:Tuple,Y} end
915+
struct FnType{X<:Tuple,Y,Z} end
916916

917917
(f::Symbolic{<:FnType})(args...) = Term{promote_symtype(f, symtype.(args)...)}(f, Any[args...])
918918

@@ -1021,8 +1021,16 @@ function _name_type(x)
10211021
lhs, rhs = x.args[1:2]
10221022
if lhs isa Expr && lhs.head === :call
10231023
# e.g. f(::Real)::Unreal
1024+
if lhs.args[1] isa Expr
1025+
func_name_and_type = _name_type(lhs.args[1])
1026+
name = func_name_and_type.name
1027+
functype = func_name_and_type.type
1028+
else
1029+
name = lhs.args[1]
1030+
functype = Nothing
1031+
end
10241032
type = map(x->_name_type(x).type, lhs.args[2:end])
1025-
return (name=lhs.args[1], type=:($FnType{Tuple{$(type...)}, $rhs}))
1033+
return (name=name, type=:($FnType{Tuple{$(type...)}, $rhs, $functype}))
10261034
else
10271035
return (name=lhs, type=rhs)
10281036
end

test/basics.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ using Test
66

77
@testset "@syms" begin
88
let
9-
@syms a b::Float64 f(::Real) g(p, h(q::Real))::Int
9+
@syms a b::Float64 f(::Real) g(p, h(q::Real))::Int
1010

1111
@test issym(a) && symtype(a) == Number
1212
@test a.name === :a
@@ -16,9 +16,11 @@ using Test
1616

1717
@test issym(f)
1818
@test f.name === :f
19+
@test symtype(f) == FnType{Tuple{Real}, Number, Nothing}
1920

2021
@test issym(g)
2122
@test g.name === :g
23+
@test symtype(g) == FnType{Tuple{Number, FnType{Tuple{Real}, Number, Nothing}}, Int, Nothing}
2224

2325
@test isterm(f(b))
2426
@test symtype(f(b)) === Number
@@ -32,6 +34,21 @@ using Test
3234
# issue #91
3335
@syms h(a,b,c)
3436
@test isequal(h(1,2,3), h(1,2,3))
37+
38+
@syms (f::typeof(max))(::Real, ::AbstractFloat)::Number a::Real
39+
@test issym(f)
40+
@test f.name == :f
41+
@test symtype(f) == FnType{Tuple{Real, AbstractFloat}, Number, typeof(max)}
42+
@test isterm(f(a, b))
43+
@test symtype(f(a, b)) == Number
44+
45+
@syms g(p, (h::typeof(identity))(q::Real)::Number)::Number
46+
@test issym(g)
47+
@test g.name == :g
48+
@test symtype(g) == FnType{Tuple{Number, FnType{Tuple{Real}, Number, typeof(identity)}}, Number, Nothing}
49+
@test_throws "not a subtype of" g(a, f)
50+
@syms (f::typeof(identity))(::Real)::Number
51+
@test symtype(g(a, f)) == Number
3552
end
3653
end
3754

0 commit comments

Comments
 (0)