Ответ 1
Я бы согласился с hammar, это похоже на ошибку. И, кажется, это исправлено в HEAD с некоторого времени. С более старым ghc-7.7.20130312
, а также с сегодняшним HEAD ghc-7.7.20130521
исключается исключение WrongArgumentCount
и удаляется весь другой код main
(хулиган для оптимизатора). Тем не менее, все еще сломанный в 7.6.3.
Поведение изменилось в серии 7.2, я получил ожидаемый WrongArgumentCount
от 7.0.4, а (оптимизированное) ядро делает это ясным:
Main.main1 =
\ (s_a11H :: GHC.Prim.State# GHC.Prim.RealWorld) ->
case GHC.List.$wlen
@ GHC.Base.String (GHC.Types.[] @ GHC.Base.String) 0
of _ {
__DEFAULT ->
case GHC.Prim.raiseIO#
@ GHC.Exception.SomeException @ () Main.main7 s_a11H
of _ { (# new_s_a11K, _ #) ->
Main.main2 new_s_a11K
};
3 -> Main.main2 s_a11H
}
когда длина пустого списка отличается от 3, поднимите WrongArgumentCount
, в противном случае попробуйте сделать все остальное.
С 7.2 и позже оценка длины перемещается за разбор < <27 > :
Main.main1 =
\ (eta_Xw :: GHC.Prim.State# GHC.Prim.RealWorld) ->
case Main.main7 of _ {
[] -> case Data.Maybe.fromJust1 of wild1_00 { };
: ds_dTy ds1_dTz ->
case ds_dTy of _ { (x_aOz, ds2_dTA) ->
case ds2_dTA of _ {
[] ->
case ds1_dTz of _ {
[] ->
case GHC.List.$wlen
@ [GHC.Types.Char] (GHC.Types.[] @ [GHC.Types.Char]) 0
of _ {
__DEFAULT ->
case GHC.Prim.raiseIO#
@ GHC.Exception.SomeException @ () Main.main6 eta_Xw
of wild4_00 {
};
3 ->
где
Main.main7 =
Text.ParserCombinators.ReadP.run
@ GHC.Integer.Type.Integer Main.main8 Main.main3
Main.main8 =
GHC.Read.$fReadInteger5
GHC.Read.$fReadInteger_$sconvertInt
Text.ParserCombinators.ReadPrec.minPrec
@ GHC.Integer.Type.Integer
(Text.ParserCombinators.ReadP.$fMonadP_$creturn
@ GHC.Integer.Type.Integer)
Main.main3 = case lvl_r1YS of wild_00 { }
lvl_r1YS =
Control.Exception.Base.irrefutPatError
@ ([GHC.Types.Char], [GHC.Types.Char], [GHC.Types.Char])
"Except.hs:21:9-34|[portStr, cert, pw]"
Так как throwIO
должен уважать порядок действий IO
,
Вариант
throwIO
следует использовать для предпочтения throw для создания исключения в монадеIO
, поскольку он гарантирует упорядочение по отношению к другим операциямIO
, тогда как throw не делает.
что не должно происходить.
Вы можете принудительно настроить порядок, используя вариант NOINLINE
when
или выполнив эффектное действие IO
перед броском, поэтому кажется, что когда inliner видит, что when
ничего не делает, кроме, возможно, бросая, он решает, что порядок не имеет значения.
(Извините, не настоящий ответ, но постарайтесь вставить это в комментарий;)