<Practical Web Development with Haskell Master the Essential> 勘误

本文档为《Practical Web Development with Haskell Master the Essential Skills to Build Fast and Scalable Web Applications》勘误文档

操作系统  mac 10.15.7

1.安装stack[P19]

我采用curl方式进行安装

2.IDE [P21]

书中采用Haskero。但是经过blog确认,此插件已经不在维护,我安装VsCode和Haskell(legacy).所以跳过`stack build intero`

这里因为要安装旧版本的ghc,需要在stack.yaml中,更新下resolver为`lts-14.21`,并且屏蔽掉其他已经打开的resolver,这样才能下载8.4.2  8.6.5的ghc,否则默认会下载8.10版本,后续的package安装会有点问题。

2.1 getZonedTime[P37]

getZonedTime存在于多个time相关package中,按照上面的添加了time-lens后,需要在repl中先引入包 import Data.Time.Lens

然后才能使用zt <- getZonedTime

 

3.Regular Expression[P38]

3.1 首先安装pcre,这里没有采用brew进行安装,直接使用裸装。步骤如下

http://www.pcre.org
curl --rempote-name https://ftp.pcre.org/pub/pcre/pcre-8.44.tar.gz
tar -xzvf pcre-8.44.tar.gz
./configure --prefix=/Users/brant/program/libs/pcre-8.44-bin
make
make install
sudo ln -s /Users/brant/program/libs/pcre-8.44-bin /usr/local/pcre
echo 'export PATH=/usr/local/pcre/bin:$PATH' >> ~/.bash_profile
source ~/.bash_profile
pcre-config --version

3.2 安装pkg-config,步骤如下(这里注意需要安装0.29.2版本。如果安装0.29版本则会在高版本的mac上出现编译错误)

curl --remote-name https://pkgconfig.freedesktop.org/releases/pkg-config-0.29.2.tar.gz
tar -zxvf pkg-config-0.29.2.tar.gz
LDFLAGS="-framework CoreFoundation -framework Carbon"
./configure --with-internal-glib
make 
sudo make install

3.3这里安装完毕后,按道理应该可以自动引入pcre.h,但是在我的环境中是找不到的,所以我采用了一个折衷的办法

编译
stack. build --extra-iunclude-dirs=/usr/local/pcre/include

执行repl
stack repl --extra-iunclude-dirs=/usr/local/pcre/include

如此便可以正确执行书中的regual相关代码

4.Json[44]

需要注意,因为我们上面已经新建了项目和main.hs,所以大部分同学应该在这里已经切换到非repl中执行了。

书中的代码‘$(deriveJSON defaultOptions "User)’ 在.hs文件中要修改为

 instance ToJSON User where
     toJSON (User uId name hobbies) = object [ "id" .= uId , "name" .= name,"hobbies" .= hobbies ]
 instance FromJSON User where
    parseJSON = withObject "User" $ \v -> User <$> v .: "id" <*> v .: "name" <*> v .: "hobbies"

-- 上面和下面等价。注意没有$()

 deriveJSON defaultOptions ''User

4.Exception[P48]

书中说因为ClassyPrelude自动引入了safe-exceptions.所以就自动获得了throw.但是我实际执行下来是没有自动引入的。如果非手动导入会获得如下错误

<interactive>:1:7: error:
    Variable not in scope: throw :: MyException -> IO ()

解决办法肯定是自己手动导入

import Control.Exception.Safe (throw)

至此,相关代码如下

package.yaml

dependencies:
- base >= 4.7 && < 5
- classy-prelude
- time
- time-lens
- pcre-heavy
- aeson
- template-haskell
- text
- safe-exceptions

default-extensions:
- NoImplicitPrelude
- OverloadedStrings
- QuasiQuotes
- TemplateHaskell
- DeriveGeneric
- DeriveAnyClass

stack.yaml

# resolver: lts-3.5
# resolver: nightly-2015-09-21
# resolver: ghc-7.10.2
resolver: lts-14.21


Main.hs

module Main where


import ClassyPrelude
import Lib
import GHC.Generics
import Data.Aeson
import Language.Haskell.TH.Syntax (nameBase)  
import Data.Aeson.TH
import Data.Aeson.TH (deriveJSON, defaultOptions)
import Control.Exception.Safe (throw)


data User = User{ userId :: Int, userName :: Text, userHobbies :: [Text] } deriving (Show, Generic)

-- instance ToJSON User where
--     toJSON (User uId name hobbies) = object [ "id" .= uId , "name" .= name,"hobbies" .= hobbies ]
-- instance FromJSON User where
--    parseJSON = withObject "User" $ \v -> User <$> v .: "id" <*> v .: "name" <*> v .: "hobbies"
-- deriveJSON defaultOptions ''User

let structName = nameBase ''User
    lowercaseFirst (x:xs) = toLower [x] <> xs 
    lowercaseFirst xs = xs
    options = defaultOptions{ fieldLabelModifier = lowercaseFirst . drop (length structName)
    }
    in deriveJSON options ''User

--- 如果想要替换生成的key格式,可以使用 camelTo2 替换 lowercaseFirst
-- camelTo2 :: Char -> String -> String
-- Here’s a usage example:
-- camelTo2 '_' 'CamelAPICase' == "camel_api_case" 
-- camelTo2 '-' 'userHobbies' == "user-hobbies"


-- isBelow10 :: Int -> Bool
-- isBelow10 n = if n < 10 then True else (error "above 10!")

isBelow10E :: Int -> Either Text ()
isBelow10E  n  = if n < 10 then Right() else Left (error "above 10!")


run :: Int ->  IO ()
run n = case isBelow10E n  of 
            Left e -> do
                putStrLn "some went wrong!"
                putStrLn e
            Right _ ->
                putStrLn "All good!"

main :: IO ()
main = someFunc 


data ServerException = ServerOnFireException | ServerNotPluggedInException deriving(Show)
instance Exception ServerException
data MyException = ThisException | ThatException deriving(Show)
instance Exception MyException 

run1 :: IO () -> IO ()
run1 action = action
            `catch` (\e -> putStrLn $  tshow (e::ServerException) )
            `catch` (\e -> putStrLn $  tshow (e::MyException))
            `catchAny` (\e -> putStrLn $ tshow e)




 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值