@@ -245,6 +245,9 @@ defmodule Module.Types.Apply do
245245
246246 ## Map
247247 { Map , :from_struct , [ { [ open_map ( ) ] , open_map ( __struct__: not_set ( ) ) } ] } ,
248+ { Map , :get , [ { [ open_map ( ) , term ( ) ] , term ( ) } ] } ,
249+ { Map , :get , [ { [ open_map ( ) , term ( ) , term ( ) ] , term ( ) } ] } ,
250+ { Map , :get_lazy , [ { [ open_map ( ) , term ( ) , fun ( 0 ) ] , term ( ) } ] } ,
248251 { Map , :pop , [ { [ open_map ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
249252 { Map , :pop , [ { [ open_map ( ) , term ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
250253 { Map , :pop! , [ { [ open_map ( ) , term ( ) ] , tuple ( [ term ( ) , open_map ( ) ] ) } ] } ,
@@ -409,40 +412,6 @@ defmodule Module.Types.Apply do
409412 end
410413 end
411414
412- defp remote_apply ( :maps , :from_keys , _info , [ list , value_type ] = args_types , stack ) do
413- case list_of ( list ) do
414- { true , nil } ->
415- { :ok , return ( empty_map ( ) , args_types , stack ) }
416-
417- { empty_list? , key_type } ->
418- if key_type == dynamic ( ) or key_type == term ( ) do
419- { :ok , return ( open_map ( ) , args_types , stack ) }
420- else
421- value_type = if_set ( value_type )
422- domain_keys = to_domain_keys ( key_type )
423-
424- keys =
425- case atom_fetch ( key_type ) do
426- { :finite , atom_keys } -> [ List . delete ( domain_keys , :atom ) | atom_keys ]
427- _ -> [ domain_keys ]
428- end
429-
430- map = closed_map ( Enum . map ( keys , & { & 1 , value_type } ) )
431-
432- map_and_maybe_empty_map =
433- case empty_list? do
434- true -> map
435- false -> difference ( map , empty_map ( ) )
436- end
437-
438- { :ok , return ( map_and_maybe_empty_map , args_types , stack ) }
439- end
440-
441- :badproperlist ->
442- { :error , badremote ( :maps , :from_keys , args_types ) }
443- end
444- end
445-
446415 @ struct_key atom ( [ :__struct__ ] )
447416 @ nil_atom atom ( [ nil ] )
448417
@@ -454,6 +423,36 @@ defmodule Module.Types.Apply do
454423 end
455424 end
456425
426+ defp remote_apply ( Map , :get , _info , [ map , key ] = args_types , stack ) do
427+ case map_get ( map , key ) do
428+ { :ok , value } -> { :ok , return ( union ( value , @ nil_atom ) , args_types , stack ) }
429+ :badmap -> { :error , badremote ( :maps , :get , args_types ) }
430+ :error -> { :error , { :badkeydomain , map , key , @ nil_atom } }
431+ end
432+ end
433+
434+ defp remote_apply ( Map , :get , _info , [ map , key , default ] = args_types , stack ) do
435+ case map_get ( map , key ) do
436+ { :ok , value } -> { :ok , return ( union ( value , default ) , args_types , stack ) }
437+ :badmap -> { :error , badremote ( :maps , :get , args_types ) }
438+ :error -> { :error , { :badkeydomain , map , key , default } }
439+ end
440+ end
441+
442+ defp remote_apply ( Map , :get_lazy , _info , [ map , key , fun ] = args_types , stack ) do
443+ case fun_apply ( fun , [ ] ) do
444+ { :ok , default } ->
445+ case map_get ( map , key ) do
446+ { :ok , value } -> { :ok , return ( union ( value , default ) , args_types , stack ) }
447+ :badmap -> { :error , badremote ( :maps , :get , args_types ) }
448+ :error -> { :error , { :badkeydomain , map , key , default } }
449+ end
450+
451+ reason ->
452+ { :error , { :badapply , fun , [ ] , reason } }
453+ end
454+ end
455+
457456 defp remote_apply ( Map , :pop , _info , args_types , stack ) do
458457 [ map , key , default ] =
459458 case args_types do
@@ -522,6 +521,40 @@ defmodule Module.Types.Apply do
522521 end
523522 end
524523
524+ defp remote_apply ( :maps , :from_keys , _info , [ list , value_type ] = args_types , stack ) do
525+ case list_of ( list ) do
526+ { true , nil } ->
527+ { :ok , return ( empty_map ( ) , args_types , stack ) }
528+
529+ { empty_list? , key_type } ->
530+ if key_type == dynamic ( ) or key_type == term ( ) do
531+ { :ok , return ( open_map ( ) , args_types , stack ) }
532+ else
533+ value_type = if_set ( value_type )
534+ domain_keys = to_domain_keys ( key_type )
535+
536+ keys =
537+ case atom_fetch ( key_type ) do
538+ { :finite , atom_keys } -> [ List . delete ( domain_keys , :atom ) | atom_keys ]
539+ _ -> [ domain_keys ]
540+ end
541+
542+ map = closed_map ( Enum . map ( keys , & { & 1 , value_type } ) )
543+
544+ map_and_maybe_empty_map =
545+ case empty_list? do
546+ true -> map
547+ false -> difference ( map , empty_map ( ) )
548+ end
549+
550+ { :ok , return ( map_and_maybe_empty_map , args_types , stack ) }
551+ end
552+
553+ :badproperlist ->
554+ { :error , badremote ( :maps , :from_keys , args_types ) }
555+ end
556+ end
557+
525558 defp remote_apply ( :maps , :get , _info , [ key , map ] = args_types , stack ) do
526559 case map_get ( map , key ) do
527560 { :ok , value } -> { :ok , return ( value , args_types , stack ) }
0 commit comments