Liquid haskell говорит, что сервер безопасен, когда это не так
У меня есть сервер в Haskell, который отвечает на входные данные Json. Проблема в том, что в некоторых случаях происходит сбой сервера из-за частичной функции, но Liquid Haskell утверждает, что это безопасно.
Вот минимальный рабочий пример:
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE DeriveGeneric #-}
module Main where
import qualified Web.Scotty as Scot
import GHC.Generics (Generic)
import qualified Data.Aeson as Json
import Data.Text.Internal.Lazy (Text)
main :: IO ()
main =
Scot.scotty 3000 $
Scot.get "/:queryJson" $ do
rawRequest <- Scot.param "queryJson"
case Json.decode rawRequest of
Nothing -> Scot.text "Could not decode input."
Just input -> Scot.text $ makeOutput (dim1 input)
{-@ type Dim = { x : Int | x >= 0 && x <= 1 } @-}
{-@ makeOutput :: Dim -> Text @-}
makeOutput :: Int -> Text
makeOutput dim =
case dim of
0 -> "a"
1 -> "b"
_ -> error "Liquid haskell should stop this happening."
{-@ dim1 :: Input -> Dim @-}
data Input = Input
{ dim1 :: Int
} deriving (Generic)
instance Json.FromJSON Input
Ликвид Хаскелл говорит, что это безопасно, но я могу разбить его, посетив http://localhost:3000/{"dim1": 2}.
Что бы я хотел, чтобы Liquid Haskell сказал мне, что аннотация для функции 'dim1' недопустима, потому что он не может быть уверен, что ввод будет 0 или 1.
Редактировать:
Я обнаружил, что если я вручную создаю функцию доступа для dim1 в Input, например:
{-@ dim1get :: Input -> Dim @-}
dim1get :: Input -> Int
dim1get (Input x) = x
и использовать это вместо функции 'dim1', тогда я получаю необходимое предупреждение от Liquid Haskell, что код небезопасен.