转换为Pointfree风格?

Kev*_*ith 2 haskell pointfree

了解一下Haskell讨论了"使Monad"具有以下Prob类型:

import Data.Ratio

newtype Prob a = Prob { getProb :: [(a,Rational)] } deriving Show  
Run Code Online (Sandbox Code Playgroud)

Prob表示一种a类型,然后Rational表示使用它的概率a.

我们来看一个Prob实例:

*Main> Prob [('a', 1%2), ('b', 1%2)]
Prob {getProb = [('a',1 % 2),('b',1 % 2)]}
Run Code Online (Sandbox Code Playgroud)

LYAH提出了一个练习,以确定如何将thisSituation类型Prob(Prob Char)转换为Prob Char:

thisSituation :: Prob (Prob Char)
thisSituation = Prob
  [( Prob [('a', 1%2),('b',1%2)], 1%4)
  ,( Prob [('c', 1%2),('d',1%2)], 3%4)
  ]
Run Code Online (Sandbox Code Playgroud)

这是我想出的:

flatten :: Prob (Prob a) -> Prob a
flatten pp = Prob $ convert $ getProb pp

convert :: [(Prob a, Rational)] -> [(a, Rational)]
convert xs = concat $ map f xs

f :: (Prob a, Rational) -> [(a, Rational)]
f (p, r) = map (mult r) (getProb p)

mult :: Rational -> (a, Rational) -> (a, Rational)
mult r (x, y) = (x, r*y)
Run Code Online (Sandbox Code Playgroud)

我试过point-free这样:

flatten :: Prob (Prob a) -> Prob a
flatten = Prob $ convert $ getProb 
Run Code Online (Sandbox Code Playgroud)

但得到了这个错误:

*Main> :l MakingMonad.hs
[1 of 1] Compiling Main             ( MakingMonad.hs, interpreted )

MakingMonad.hs:37:11:
    Couldn't match expected type `Prob (Prob a) -> Prob a'
                with actual type `Prob a0'
    In the expression: Prob $ convert $ getProb
    In an equation for `flatten': flatten = Prob $ convert $ getProb

MakingMonad.hs:37:28:
    Couldn't match expected type `[(Prob a0, Rational)]'
                with actual type `Prob a1 -> [(a1, Rational)]'
    In the second argument of `($)', namely `getProb'
    In the second argument of `($)', namely `convert $ getProb'
    In the expression: Prob $ convert $ getProb
Failed, modules loaded: none.
Run Code Online (Sandbox Code Playgroud)

我可以flatten点免费吗?如果是这样,请告诉我如何.如果没有,请解释原因.

Her*_*ton 7

当您使用$in时flatten,您将获得看起来像的代码

flatten = Prob $ convert $ getProb
==> Prob (convert (getProb))
Run Code Online (Sandbox Code Playgroud)

这不是你想要的.

你要 Prob . convert . getProb

  • @KevinMeredith当您编写`Prob(转换getProb)`时,您将`(转换getProb)`传递给`Prob`作为参数.`Prob`不接受函数作为参数,`convert`也不接受函数作为参数,因此你得到类型错误. (3认同)