BingWallpapers: Fetches and applies the image of the day from Bing as the wallpaper
up vote
5
down vote
favorite
I have written a small desktop program nabeelomer/BingWallpapers in Haskell. This is my first time writing Haskell.
I was wondering how I can make the code use more functional programming features/idioms/patterns.
Any other suggestions on how to improve the code are also welcome.
-- Copyright (C) Nabeel Omer 2017
-- See the LICENSE file for the license
--
import Network.HTTP.Conduit
import System.Process
import qualified Data.ByteString.Lazy.Char8 as L8
import GHC.IO.Exception
main :: IO ()
main = do
-- using http://muzzammil.xyz/git/bing/
metadata <- get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
-- Guaranteed by the API
putStrLn $ (split '>' $ (lines $ L8.unpack metadata)!!1)!!1
let url = (lines $ L8.unpack metadata)!!0
picture <- get $ (split '>' url)!!1
L8.writeFile "/dev/shm/Bing-Wallpaper" picture
exitcode <- setWallpaper "/dev/shm/Bing-Wallpaper"
print exitcode
return ()
-- From StackOverflow
split :: Eq a => a -> [a] -> [[a]]
split d =
split d s = x : split d (drop 1 y) where (x,y) = span (/= d) s
get :: String -> IO L8.ByteString
get url = simpleHttp url
setWallpaper :: String -> IO GHC.IO.Exception.ExitCode
setWallpaper uri = system $ "gsettings set org.gnome.desktop.background picture-uri file://" ++ uri
beginner haskell http
add a comment |
up vote
5
down vote
favorite
I have written a small desktop program nabeelomer/BingWallpapers in Haskell. This is my first time writing Haskell.
I was wondering how I can make the code use more functional programming features/idioms/patterns.
Any other suggestions on how to improve the code are also welcome.
-- Copyright (C) Nabeel Omer 2017
-- See the LICENSE file for the license
--
import Network.HTTP.Conduit
import System.Process
import qualified Data.ByteString.Lazy.Char8 as L8
import GHC.IO.Exception
main :: IO ()
main = do
-- using http://muzzammil.xyz/git/bing/
metadata <- get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
-- Guaranteed by the API
putStrLn $ (split '>' $ (lines $ L8.unpack metadata)!!1)!!1
let url = (lines $ L8.unpack metadata)!!0
picture <- get $ (split '>' url)!!1
L8.writeFile "/dev/shm/Bing-Wallpaper" picture
exitcode <- setWallpaper "/dev/shm/Bing-Wallpaper"
print exitcode
return ()
-- From StackOverflow
split :: Eq a => a -> [a] -> [[a]]
split d =
split d s = x : split d (drop 1 y) where (x,y) = span (/= d) s
get :: String -> IO L8.ByteString
get url = simpleHttp url
setWallpaper :: String -> IO GHC.IO.Exception.ExitCode
setWallpaper uri = system $ "gsettings set org.gnome.desktop.background picture-uri file://" ++ uri
beginner haskell http
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I have written a small desktop program nabeelomer/BingWallpapers in Haskell. This is my first time writing Haskell.
I was wondering how I can make the code use more functional programming features/idioms/patterns.
Any other suggestions on how to improve the code are also welcome.
-- Copyright (C) Nabeel Omer 2017
-- See the LICENSE file for the license
--
import Network.HTTP.Conduit
import System.Process
import qualified Data.ByteString.Lazy.Char8 as L8
import GHC.IO.Exception
main :: IO ()
main = do
-- using http://muzzammil.xyz/git/bing/
metadata <- get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
-- Guaranteed by the API
putStrLn $ (split '>' $ (lines $ L8.unpack metadata)!!1)!!1
let url = (lines $ L8.unpack metadata)!!0
picture <- get $ (split '>' url)!!1
L8.writeFile "/dev/shm/Bing-Wallpaper" picture
exitcode <- setWallpaper "/dev/shm/Bing-Wallpaper"
print exitcode
return ()
-- From StackOverflow
split :: Eq a => a -> [a] -> [[a]]
split d =
split d s = x : split d (drop 1 y) where (x,y) = span (/= d) s
get :: String -> IO L8.ByteString
get url = simpleHttp url
setWallpaper :: String -> IO GHC.IO.Exception.ExitCode
setWallpaper uri = system $ "gsettings set org.gnome.desktop.background picture-uri file://" ++ uri
beginner haskell http
I have written a small desktop program nabeelomer/BingWallpapers in Haskell. This is my first time writing Haskell.
I was wondering how I can make the code use more functional programming features/idioms/patterns.
Any other suggestions on how to improve the code are also welcome.
-- Copyright (C) Nabeel Omer 2017
-- See the LICENSE file for the license
--
import Network.HTTP.Conduit
import System.Process
import qualified Data.ByteString.Lazy.Char8 as L8
import GHC.IO.Exception
main :: IO ()
main = do
-- using http://muzzammil.xyz/git/bing/
metadata <- get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
-- Guaranteed by the API
putStrLn $ (split '>' $ (lines $ L8.unpack metadata)!!1)!!1
let url = (lines $ L8.unpack metadata)!!0
picture <- get $ (split '>' url)!!1
L8.writeFile "/dev/shm/Bing-Wallpaper" picture
exitcode <- setWallpaper "/dev/shm/Bing-Wallpaper"
print exitcode
return ()
-- From StackOverflow
split :: Eq a => a -> [a] -> [[a]]
split d =
split d s = x : split d (drop 1 y) where (x,y) = span (/= d) s
get :: String -> IO L8.ByteString
get url = simpleHttp url
setWallpaper :: String -> IO GHC.IO.Exception.ExitCode
setWallpaper uri = system $ "gsettings set org.gnome.desktop.background picture-uri file://" ++ uri
beginner haskell http
beginner haskell http
edited Jun 26 '17 at 5:55
asked Jun 25 '17 at 20:38
1 -_-
265
265
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Pattern matching instead of !!
, inlining of single-use names where straightforward.
import Data.List.Split
main = do
(_:picurl:_):(_:title:_):_ <- map (wordsBy (=='>')) . lines . L8.unpack
<$> get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
putStrLn title
L8.writeFile "/dev/shm/Bing-Wallpaper" =<< get picurl
print =<< setWallpaper "/dev/shm/Bing-Wallpaper"
Can you please explain how themap (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?
– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym forfmap
, andfmap f x
is likex >>= return . f
for monads.map
appliesData.List.Split
's wording ofsplit
to both lines where you'd do it to each manually.(f . g) x = f (g x)
and.
has higher precedence than<$>
, so all of the left of<$>
isfmap
ed over its right. Feel free to keep your comments around, of course.
– Gurkenglas
Jun 27 '17 at 21:08
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Pattern matching instead of !!
, inlining of single-use names where straightforward.
import Data.List.Split
main = do
(_:picurl:_):(_:title:_):_ <- map (wordsBy (=='>')) . lines . L8.unpack
<$> get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
putStrLn title
L8.writeFile "/dev/shm/Bing-Wallpaper" =<< get picurl
print =<< setWallpaper "/dev/shm/Bing-Wallpaper"
Can you please explain how themap (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?
– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym forfmap
, andfmap f x
is likex >>= return . f
for monads.map
appliesData.List.Split
's wording ofsplit
to both lines where you'd do it to each manually.(f . g) x = f (g x)
and.
has higher precedence than<$>
, so all of the left of<$>
isfmap
ed over its right. Feel free to keep your comments around, of course.
– Gurkenglas
Jun 27 '17 at 21:08
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
add a comment |
up vote
0
down vote
Pattern matching instead of !!
, inlining of single-use names where straightforward.
import Data.List.Split
main = do
(_:picurl:_):(_:title:_):_ <- map (wordsBy (=='>')) . lines . L8.unpack
<$> get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
putStrLn title
L8.writeFile "/dev/shm/Bing-Wallpaper" =<< get picurl
print =<< setWallpaper "/dev/shm/Bing-Wallpaper"
Can you please explain how themap (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?
– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym forfmap
, andfmap f x
is likex >>= return . f
for monads.map
appliesData.List.Split
's wording ofsplit
to both lines where you'd do it to each manually.(f . g) x = f (g x)
and.
has higher precedence than<$>
, so all of the left of<$>
isfmap
ed over its right. Feel free to keep your comments around, of course.
– Gurkenglas
Jun 27 '17 at 21:08
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
add a comment |
up vote
0
down vote
up vote
0
down vote
Pattern matching instead of !!
, inlining of single-use names where straightforward.
import Data.List.Split
main = do
(_:picurl:_):(_:title:_):_ <- map (wordsBy (=='>')) . lines . L8.unpack
<$> get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
putStrLn title
L8.writeFile "/dev/shm/Bing-Wallpaper" =<< get picurl
print =<< setWallpaper "/dev/shm/Bing-Wallpaper"
Pattern matching instead of !!
, inlining of single-use names where straightforward.
import Data.List.Split
main = do
(_:picurl:_):(_:title:_):_ <- map (wordsBy (=='>')) . lines . L8.unpack
<$> get "http://cdn.muzzammil.xyz/bing/bing.php?format=text&cc=IN"
putStrLn title
L8.writeFile "/dev/shm/Bing-Wallpaper" =<< get picurl
print =<< setWallpaper "/dev/shm/Bing-Wallpaper"
answered Jun 27 '17 at 13:53
Gurkenglas
2,728511
2,728511
Can you please explain how themap (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?
– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym forfmap
, andfmap f x
is likex >>= return . f
for monads.map
appliesData.List.Split
's wording ofsplit
to both lines where you'd do it to each manually.(f . g) x = f (g x)
and.
has higher precedence than<$>
, so all of the left of<$>
isfmap
ed over its right. Feel free to keep your comments around, of course.
– Gurkenglas
Jun 27 '17 at 21:08
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
add a comment |
Can you please explain how themap (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?
– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym forfmap
, andfmap f x
is likex >>= return . f
for monads.map
appliesData.List.Split
's wording ofsplit
to both lines where you'd do it to each manually.(f . g) x = f (g x)
and.
has higher precedence than<$>
, so all of the left of<$>
isfmap
ed over its right. Feel free to keep your comments around, of course.
– Gurkenglas
Jun 27 '17 at 21:08
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
Can you please explain how the
map (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?– 1 -_-
Jun 27 '17 at 19:08
Can you please explain how the
map (wordsBy (=='>')) . lines . L8.unpack <$> get
part works?– 1 -_-
Jun 27 '17 at 19:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym for fmap
, and fmap f x
is like x >>= return . f
for monads. map
applies Data.List.Split
's wording of split
to both lines where you'd do it to each manually. (f . g) x = f (g x)
and .
has higher precedence than <$>
, so all of the left of <$>
is fmap
ed over its right. Feel free to keep your comments around, of course.– Gurkenglas
Jun 27 '17 at 21:08
(<$>) :: Functor f => (a -> b) -> f a -> f b
is an infix synonym for fmap
, and fmap f x
is like x >>= return . f
for monads. map
applies Data.List.Split
's wording of split
to both lines where you'd do it to each manually. (f . g) x = f (g x)
and .
has higher precedence than <$>
, so all of the left of <$>
is fmap
ed over its right. Feel free to keep your comments around, of course.– Gurkenglas
Jun 27 '17 at 21:08
1
1
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
You have presented an alternative solution, but only slightly reviewed the code. Please explain your reasoning (how your solution works and why it is better than the original) in the post, not in the comments, so that the author and other readers can learn from your thought process.
– Zeta
Jun 29 '17 at 7:05
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f166622%2fbingwallpapers-fetches-and-applies-the-image-of-the-day-from-bing-as-the-wallpa%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown